Re: [libvirt] Memory free in libvirt JNA

Hi, I wrote a code to verify the memory leak problem as following. C code in so: void checkJNAMemLeak1(int **head, int *length) { long i = 0; *head = (int *)malloc(sizeof(int) * 100000000); for(i=0; i<100000000; i++) { (*head)[i] = 1; } *length = 100000000; } Java code: public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference(); while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1); } } When we check memory by top command, the virt and res will increase very quickly. When we check with jconsole, there is no memory in Java heap. Even I execute GC manually by jconsole. Nothing happen. If I change java code as following: public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference(); while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1); libc.free(head.getValue()); } } public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference(); while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1); libc.free(head.getValue()); } } Then everything works well. The virt and res will not increase. I think we must provide the free functions for all the memory allocated by libvirt. B.R. Benjamin Wang -----Original Message----- From: Benjamin Wang (gendwang) Sent: 2012年9月7日 15:22 To: libvir-list@redhat.com Cc: 'veillard@redhat.com'; Yang Zhou (yangzho) Subject: RE: Memory free in libvirt JNA Hi, Overview Part of JNA API describes as following: 1. Description1: If the native method returns char* and actually allocates memory, a return type of Pointer should be used to avoid leaking the memory. It is then up to you to take the necessary steps to free the allocated memory. 2. Description2: Declare the method as returning a Structure of the appropriate type, then invoke Structure.toArray(int) to convert to an array of initialized structures of the appropriate size. Note that your Structure class must have a no-args constructor, and you are responsible for freeing the returned memory if applicable in whatever way is appropriate for the called function. And the example code shows as following: // Original C code struct Display* get_displays(int* pcount); void free_displays(struct Display* displays); // Equivalent JNA mapping Display get_displays(IntByReference pcount); void free_displays(Display[] displays); ... IntByReference pcount = new IntByReference(); Display d = lib.get_displays(pcount); Display[] displays = (Display[])d.toArray(pcount.getValue()); ... lib.free_displays(displays); That's to say. All the memory allocated by native code must be freed explicitly in JNA part. We must add some free memory methods to support the memory-freeing. Any comments? B.R. Benjamin Wang -----Original Message----- From: Daniel Veillard [mailto:veillard@redhat.com] Sent: 2012年8月20日 14:25 To: Benjamin Wang (gendwang) Cc: stoty@tvnet.hu; Daniel.Schwager@dtnet.de Subject: Re: Memory free in libvirt JNA On Mon, Aug 20, 2012 at 05:15:45AM +0000, Benjamin Wang (gendwang) wrote:
Hi Veillard, Thanks for your reply. I checked the current Libvirt-JNA implementation. I find that a method named "free" defined in Domain class which is used to free the domain object. If this is mandatory, that's to say, we should a lot of methods into the current Libvirt-jna implementation to free the memory which is allocated by libvirt API. Please correct me!
As far as I understat free() is aliased as finalize() on that object so the java runtime will call free() automatically on garbage collection. I'm not a java expert, check some Java litterature for more details about how this is done and the cases where free() might be better called directly. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Sun, Sep 09, 2012 at 02:09:45PM +0000, Benjamin Wang (gendwang) wrote:
Hi, I wrote a code to verify the memory leak problem as following. C code in so: void checkJNAMemLeak1(int **head, int *length) { long i = 0;
*head = (int *)malloc(sizeof(int) * 100000000); for(i=0; i<100000000; i++) { (*head)[i] = 1; }
*length = 100000000; }
Java code: public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference();
while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1);
} }
When we check memory by top command, the virt and res will increase very quickly. When we check with jconsole, there is no memory in Java heap. Even I execute GC manually by jconsole. Nothing happen.
If I change java code as following: public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference();
while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1);
libc.free(head.getValue()); } }
public static void testJNAMemLeak1() { PointerByReference head = new PointerByReference(); IntByReference length = new IntByReference();
while(true) { libben.checkJNAMemLeak1(head, length); System.out.println(length.getValue()); sleep(1);
libc.free(head.getValue()); } }
Then everything works well. The virt and res will not increase. I think we must provide the free functions for all the memory allocated by libvirt.
Okay, can you work on making a patch ? To be honnest I'm very unlikely to have time for this in the short term, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

At Wed, 12 Sep 2012 20:23:28 +0800, Daniel Veillard wrote:
I think we must provide the free functions for all the memory allocated by libvirt.
Okay, can you work on making a patch ? To be honnest I'm very unlikely to have time for this in the short term,
I did notice the same thing (but was on vacation for quite some time). I already have a fix for virDomainGetSchedulerType in my local repository (see below). I'm using virFree to free the allocated memory which adds another level of indirection (PointerByReference). This is because JNA does not provide access to the C free() function by itself, AFAICS. -- 8< ---
From cb58e9538afbfd7ce09c5c2a93e403a809e77113 Mon Sep 17 00:00:00 2001 From: Claudio Bley <cbley@av-test.de> Date: Fri, 24 Aug 2012 11:09:49 +0200 Subject: [PATCH] Fix memory leak for virDomainGetSchedulerType.
The string returned by virDomainGetSchedulerType must be free'd explicitly. JNA docs say that we have to use a Pointer as a return type and free it ourselves. So, simply use virFree for that matter. --- src/main/java/org/libvirt/Domain.java | 13 +++++++++---- src/main/java/org/libvirt/jna/Libvirt.java | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 1f15ee8..fc1f665 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -14,7 +14,9 @@ import org.libvirt.jna.virVcpuInfo; import com.sun.jna.Native; import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; /** * A virtual machine defined within libvirt. @@ -443,9 +445,11 @@ public class Domain { public SchedParameter[] getSchedulerParameters() throws LibvirtException { IntByReference nParams = new IntByReference(); SchedParameter[] returnValue = new SchedParameter[0]; - String scheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); - if (scheduler != null) { + if (pScheduler != null) { + String scheduler = pScheduler.getString(0); + libvirt.virFree(new PointerByReference(pScheduler)); virSchedParameter[] nativeParams = new virSchedParameter[nParams.getValue()]; returnValue = new SchedParameter[nParams.getValue()]; libvirt.virDomainGetSchedulerParameters(VDP, nativeParams, nParams); @@ -470,10 +474,11 @@ public class Domain { */ public String[] getSchedulerType() throws LibvirtException { IntByReference nParams = new IntByReference(); - String returnValue = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); String[] array = new String[1]; - array[0] = returnValue; + array[0] = pScheduler.getString(0); + libvirt.virFree(new PointerByReference(pScheduler)); return array; } diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index dc3a54b..e68d9ed 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -7,6 +7,7 @@ import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; +import com.sun.jna.ptr.PointerByReference; /** * The libvirt interface which is exposed via JNA. The complete API is @@ -55,6 +56,9 @@ import com.sun.jna.ptr.LongByReference; * */ public interface Libvirt extends Library { + // Memory management + void virFree(PointerByReference ptr); + // Callbacks /** * Callback interface for authorization @@ -186,7 +190,7 @@ public interface Libvirt extends Library { public String virDomainGetOSType(DomainPointer virDomainPtr); public int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, IntByReference nparams); - public String virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); + Pointer virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); public int virDomainGetUUID(DomainPointer virDomainPtr, byte[] uuidString); public int virDomainGetUUIDString(DomainPointer virDomainPtr, byte[] uuidString); public int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, int maxInfo, byte[] cpumaps, int maplen); -- 1.7.11.msysgit.0 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Hi Claudio, sorry for the delay, I need to focuse one something else ATM ! On Mon, Sep 24, 2012 at 04:11:19PM +0200, Claudio Bley wrote:
At Wed, 12 Sep 2012 20:23:28 +0800, Daniel Veillard wrote:
I think we must provide the free functions for all the memory allocated by libvirt.
Okay, can you work on making a patch ? To be honnest I'm very unlikely to have time for this in the short term,
I did notice the same thing (but was on vacation for quite some time). I already have a fix for virDomainGetSchedulerType in my local repository (see below).
okay i see
I'm using virFree to free the allocated memory which adds another level of indirection (PointerByReference). This is because JNA does not provide access to the C free() function by itself, AFAICS.
-- 8< --- From cb58e9538afbfd7ce09c5c2a93e403a809e77113 Mon Sep 17 00:00:00 2001 From: Claudio Bley <cbley@av-test.de> Date: Fri, 24 Aug 2012 11:09:49 +0200 Subject: [PATCH] Fix memory leak for virDomainGetSchedulerType.
The string returned by virDomainGetSchedulerType must be free'd explicitly.
JNA docs say that we have to use a Pointer as a return type and free it ourselves. So, simply use virFree for that matter. --- src/main/java/org/libvirt/Domain.java | 13 +++++++++---- src/main/java/org/libvirt/jna/Libvirt.java | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 1f15ee8..fc1f665 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -14,7 +14,9 @@ import org.libvirt.jna.virVcpuInfo;
import com.sun.jna.Native; import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference;
/** * A virtual machine defined within libvirt. @@ -443,9 +445,11 @@ public class Domain { public SchedParameter[] getSchedulerParameters() throws LibvirtException { IntByReference nParams = new IntByReference(); SchedParameter[] returnValue = new SchedParameter[0]; - String scheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); - if (scheduler != null) { + if (pScheduler != null) { + String scheduler = pScheduler.getString(0); + libvirt.virFree(new PointerByReference(pScheduler)); virSchedParameter[] nativeParams = new virSchedParameter[nParams.getValue()]; returnValue = new SchedParameter[nParams.getValue()]; libvirt.virDomainGetSchedulerParameters(VDP, nativeParams, nParams); @@ -470,10 +474,11 @@ public class Domain { */ public String[] getSchedulerType() throws LibvirtException { IntByReference nParams = new IntByReference(); - String returnValue = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); String[] array = new String[1]; - array[0] = returnValue; + array[0] = pScheduler.getString(0); + libvirt.virFree(new PointerByReference(pScheduler)); return array; }
diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index dc3a54b..e68d9ed 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -7,6 +7,7 @@ import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; +import com.sun.jna.ptr.PointerByReference;
/** * The libvirt interface which is exposed via JNA. The complete API is @@ -55,6 +56,9 @@ import com.sun.jna.ptr.LongByReference; * */ public interface Libvirt extends Library { + // Memory management + void virFree(PointerByReference ptr); + // Callbacks /** * Callback interface for authorization @@ -186,7 +190,7 @@ public interface Libvirt extends Library { public String virDomainGetOSType(DomainPointer virDomainPtr); public int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, IntByReference nparams); - public String virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); + Pointer virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); public int virDomainGetUUID(DomainPointer virDomainPtr, byte[] uuidString); public int virDomainGetUUIDString(DomainPointer virDomainPtr, byte[] uuidString); public int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, int maxInfo, byte[] cpumaps, int maplen);
Okay, that makes sense. First do you have a small pointer indicating where in JNA that kind of native deallocation must take place, since most of the time JNA can do the marshalling all by itself ? And second would you have an idea how to systematically detect such leaks, the kind of loop suggested to expose the issue is nor really practical to chase the leaks ... In the meantime I pushed you initial patch, thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Hi Daniel, At Fri, 28 Sep 2012 22:34:13 +0800, Daniel Veillard wrote:
sorry for the delay, I need to focuse one something else ATM !
Me too. So, no worries! ;)
First do you have a small pointer indicating where in JNA that kind of native deallocation must take place, since most of the time JNA can do the marshalling all by itself ?
This effects mostly Strings. JNA takes the safe assumption that functions are returning "const char*"s because it can't distinguish a string (const char*) from a string (char*). See https://github.com/twall/jna/blob/master/www/FrequentlyAskedQuestions.md#how... So, here is a list of methods of org.libvirt.jna.Libvirt which return a string (/probably/ a char*, not const char*) which need to be checked: virConnectBaselineCPU virConnectDomainXMLFromNative virConnectDomainXMLToNative virConnectFindStoragePoolSources virConnectGetCapabilities virConnectGetHostname virConnectGetType virConnectGetURI virDomainGetName virDomainGetOSType virDomainGetXMLDesc virDomainSnapshotGetXMLDesc virInterfaceGetMACString virInterfaceGetName virInterfaceGetXMLDesc virNWFilterGetName virNWFilterGetXMLDesc virNetworkGetBridgeName virNetworkGetName virNetworkGetXMLDesc virNodeDeviceGetName virNodeDeviceGetParent virNodeDeviceGetXMLDesc virSecretGetUsageID virSecretGetXMLDesc virStoragePoolGetName virStoragePoolGetXMLDesc virStorageVolGetKey virStorageVolGetName virStorageVolGetPath virStorageVolGetXMLDesc
And second would you have an idea how to systematically detect such leaks, the kind of loop suggested to expose the issue is nor really practical to chase the leaks ...
I tried valgrind, but it didn't produce any output. mtrace wasn't very helpful either. So, I just hacked this up: ,----[ memcheck.py ] | import gdb | | allocations = {} | | class AllocBreak(gdb.FinishBreakpoint): | def stop(self): | global allocations | | if self.return_value != None: | callstack = [] | frame = gdb.selected_frame() | | while frame: | name = frame.name() | func = frame.function() | sal = frame.find_sal() | | funcname = func.print_name if func else '?' | line = sal.line | filename = sal.symtab.filename if sal.symtab else '?' | | callstack.append((name, filename, line, funcname)) | | frame = frame.older() | | addr = int(str(self.return_value), 16) | allocations[addr] = callstack | | | class MemAlloc (gdb.Command): | "Track allocations." | def __init__(self): | super(MemAlloc, self).__init__("memalloc", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | top = gdb.selected_frame() | frame = top.older() | | if frame: | func = frame.function() | | if func: # and func.name.startswith("virAlloc"): | ab = AllocBreak(top, True) | ab.silent = True | | | class MemFree(gdb.Command): | "Track de-allocations." | def __init__(self): | super(MemFree, self).__init__("memfree", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | global allocations | | block = gdb.selected_frame().block() | while block: | for sym in block: | if sym.is_argument: | addr = int(str(gdb.parse_and_eval(sym.name)), 16) | | if addr in allocations: | del allocations[addr] | | return | block = block.superblock | | | class MemReport(gdb.Command): | def __init__(self): | super(MemReport, self).__init__("memreport", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | global allocations | | nr = 1 | for k, v in allocations.iteritems(): | print "{0}. @{1}".format(nr, k) | i = 1 | gap = 0 | nr += 1 | for name, filename, line, funcname in v: | if name: | if gap > 0: | print " #{0} ... [{1}]".format(i, gap) | i += 1 | gap = 0 | print " #{0} {1} {2} {3}:{4}".format(i, name, funcname, filename, line) | i += 1 | else: | gap += 1 | if gap > 0: | print " #{0} ... [{1}]".format(i, gap) | | MemAlloc() | MemFree() | MemReport() `---- ,----[ .gdbinit ] | set pagination off | source memcheck.py | set breakpoint pending on | | break calloc | commands | silent | memalloc | cont | end | | break free | commands | silent | memfree | cont | end | | break malloc | commands | silent | memalloc | cont | end | | disable | | tbreak virInitialize | commands | silent | finish | end `---- Just drop these two files into the current directory, so that GDB will find them. Using this short Java program ,----[ Memcheck.java ] | | package org.libvirt; | | import com.sun.jna.Library; | import com.sun.jna.Native; | | import java.io.InputStream; | import java.io.InputStreamReader; | import java.io.BufferedReader; | import java.io.FileInputStream; | import java.io.IOException; | import java.util.Set; | import java.util.HashSet; | | class Memcheck { | public static void main(String[] args) throws IOException { | Connect conn = null; | Domain dom = null; | | try { | conn = new Connect("test:///default", false); | | dom = conn.domainDefineXML("<domain type='test' id='2'>" + " <name>deftest</name>" | + " <uuid>004b96e1-2d78-c30f-5aa5-f03c87d21e70</uuid>" + " <memory>8388608</memory>" | + " <vcpu>2</vcpu>" + " <os><type arch='i686'>hvm</type></os>" | + " <on_reboot>restart</on_reboot>" + " <on_poweroff>destroy</on_poweroff>" | + " <on_crash>restart</on_crash>" + "</domain>"); | | System.out.println("virDomainGetSchedulerType:" + dom.getSchedulerType()[0]); | | dom.undefine(); | } catch (LibvirtException e) { | System.out.println("exception caught:" + e); | System.out.println(e.getError()); | } finally { | if (conn != null) | try { | dom.free(); | conn.close(); | } catch (LibvirtException e) { | } | } | } | } `---- and running gdb --args java -cp \ /usr/share/java/jna.jar:target/classes/:target/testclasses/ \ org.libvirt.Memcheck with libvirt-java @efbe26d yielded this GDB output: (gdb) run ... 0x00007fffe7dfda14 in ffi_call_unix64 () from /usr/lib/x86_64-linux-gnu/libffi.so.6 Value returned is $1 = 0 (gdb) enable (gdb) c ... (gdb) memreport 1. @140737220921872 #1 testDomainGetSchedulerType testDomainGetSchedulerType /build/buildd/libvirt-0.9.12/./src/test/test_driver.c:2679 #2 virDomainGetSchedulerType virDomainGetSchedulerType /build/buildd/libvirt-0.9.12/./src/libvirt.c:6848 #3 ffi_call_unix64 ? ?:0 #4 ffi_call ? ?:0 #5 ... [1] #6 Java_com_sun_jna_Function_invokePointer ? ?:0 #7 ... [7]
In the meantime I pushed you initial patch, thanks !
Thank you! Evidently, this really fixed the memleak above. Yay! :) -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Hi Claudio, Sorry for my late response. I have gone through Claudio's solution. It's good. But I think this is not a common solution. There are two points: 1. This solution must use Pointerbyreference to encapsulate the Pointer. This is not clean. 2. Libvirt provides virFree method. But a common library could not provide memory management functions. My proposal is as following: 1. Add a new Class Libc.java public interface Libc extends Library{ Libc INSTANCE = (Libc) Native.loadLibrary("c", Libc.class); public void free(Pointer p); } 2. Transfer the following code as following: public SchedParameter[] getSchedulerParameters() throws LibvirtException { IntByReference nParams = new IntByReference(); SchedParameter[] returnValue = new SchedParameter[0]; - String scheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); - if (scheduler != null) { + if (pScheduler != null) { + String scheduler = pScheduler.getString(0); + libc.free(pScheduler); virSchedParameter[] nativeParams = new virSchedParameter[nParams.getValue()]; returnValue = new SchedParameter[nParams.getValue()]; libvirt.virDomainGetSchedulerParameters(VDP, nativeParams, nParams); What about your opinion? B.R. Benjamin Wang -----Original Message----- From: Claudio Bley [mailto:cbley@av-test.de] Sent: 2012年10月8日 20:33 To: veillard@redhat.com Cc: Benjamin Wang (gendwang); libvir-list@redhat.com; Yang Zhou (yangzho) Subject: Re: [libvirt] Memory free in libvirt JNA Hi Daniel, At Fri, 28 Sep 2012 22:34:13 +0800, Daniel Veillard wrote:
sorry for the delay, I need to focuse one something else ATM !
Me too. So, no worries! ;)
First do you have a small pointer indicating where in JNA that kind of native deallocation must take place, since most of the time JNA can do the marshalling all by itself ?
This effects mostly Strings. JNA takes the safe assumption that functions are returning "const char*"s because it can't distinguish a string (const char*) from a string (char*). See https://github.com/twall/jna/blob/master/www/FrequentlyAskedQuestions.md#how... So, here is a list of methods of org.libvirt.jna.Libvirt which return a string (/probably/ a char*, not const char*) which need to be checked: virConnectBaselineCPU virConnectDomainXMLFromNative virConnectDomainXMLToNative virConnectFindStoragePoolSources virConnectGetCapabilities virConnectGetHostname virConnectGetType virConnectGetURI virDomainGetName virDomainGetOSType virDomainGetXMLDesc virDomainSnapshotGetXMLDesc virInterfaceGetMACString virInterfaceGetName virInterfaceGetXMLDesc virNWFilterGetName virNWFilterGetXMLDesc virNetworkGetBridgeName virNetworkGetName virNetworkGetXMLDesc virNodeDeviceGetName virNodeDeviceGetParent virNodeDeviceGetXMLDesc virSecretGetUsageID virSecretGetXMLDesc virStoragePoolGetName virStoragePoolGetXMLDesc virStorageVolGetKey virStorageVolGetName virStorageVolGetPath virStorageVolGetXMLDesc
And second would you have an idea how to systematically detect such leaks, the kind of loop suggested to expose the issue is nor really practical to chase the leaks ...
I tried valgrind, but it didn't produce any output. mtrace wasn't very helpful either. So, I just hacked this up: ,----[ memcheck.py ] | import gdb | | allocations = {} | | class AllocBreak(gdb.FinishBreakpoint): | def stop(self): | global allocations | | if self.return_value != None: | callstack = [] | frame = gdb.selected_frame() | | while frame: | name = frame.name() | func = frame.function() | sal = frame.find_sal() | | funcname = func.print_name if func else '?' | line = sal.line | filename = sal.symtab.filename if sal.symtab else '?' | | callstack.append((name, filename, line, funcname)) | | frame = frame.older() | | addr = int(str(self.return_value), 16) | allocations[addr] = callstack | | | class MemAlloc (gdb.Command): | "Track allocations." | def __init__(self): | super(MemAlloc, self).__init__("memalloc", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | top = gdb.selected_frame() | frame = top.older() | | if frame: | func = frame.function() | | if func: # and func.name.startswith("virAlloc"): | ab = AllocBreak(top, True) | ab.silent = True | | | class MemFree(gdb.Command): | "Track de-allocations." | def __init__(self): | super(MemFree, self).__init__("memfree", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | global allocations | | block = gdb.selected_frame().block() | while block: | for sym in block: | if sym.is_argument: | addr = int(str(gdb.parse_and_eval(sym.name)), 16) | | if addr in allocations: | del allocations[addr] | | return | block = block.superblock | | | class MemReport(gdb.Command): | def __init__(self): | super(MemReport, self).__init__("memreport", gdb.COMMAND_NONE) | | def invoke(self, arg, from_tty): | global allocations | | nr = 1 | for k, v in allocations.iteritems(): | print "{0}. @{1}".format(nr, k) | i = 1 | gap = 0 | nr += 1 | for name, filename, line, funcname in v: | if name: | if gap > 0: | print " #{0} ... [{1}]".format(i, gap) | i += 1 | gap = 0 | print " #{0} {1} {2} {3}:{4}".format(i, name, funcname, filename, line) | i += 1 | else: | gap += 1 | if gap > 0: | print " #{0} ... [{1}]".format(i, gap) | | MemAlloc() | MemFree() | MemReport() `---- ,----[ .gdbinit ] | set pagination off | source memcheck.py | set breakpoint pending on | | break calloc | commands | silent | memalloc | cont | end | | break free | commands | silent | memfree | cont | end | | break malloc | commands | silent | memalloc | cont | end | | disable | | tbreak virInitialize | commands | silent | finish | end `---- Just drop these two files into the current directory, so that GDB will find them. Using this short Java program ,----[ Memcheck.java ] | | package org.libvirt; | | import com.sun.jna.Library; | import com.sun.jna.Native; | | import java.io.InputStream; | import java.io.InputStreamReader; | import java.io.BufferedReader; | import java.io.FileInputStream; | import java.io.IOException; | import java.util.Set; | import java.util.HashSet; | | class Memcheck { | public static void main(String[] args) throws IOException { | Connect conn = null; | Domain dom = null; | | try { | conn = new Connect("test:///default", false); | | dom = conn.domainDefineXML("<domain type='test' id='2'>" + " <name>deftest</name>" | + " <uuid>004b96e1-2d78-c30f-5aa5-f03c87d21e70</uuid>" + " <memory>8388608</memory>" | + " <vcpu>2</vcpu>" + " <os><type arch='i686'>hvm</type></os>" | + " <on_reboot>restart</on_reboot>" + " <on_poweroff>destroy</on_poweroff>" | + " <on_crash>restart</on_crash>" + | "</domain>"); | | System.out.println("virDomainGetSchedulerType:" + | dom.getSchedulerType()[0]); | | dom.undefine(); | } catch (LibvirtException e) { | System.out.println("exception caught:" + e); | System.out.println(e.getError()); | } finally { | if (conn != null) | try { | dom.free(); | conn.close(); | } catch (LibvirtException e) { | } | } | } | } `---- and running gdb --args java -cp \ /usr/share/java/jna.jar:target/classes/:target/testclasses/ \ org.libvirt.Memcheck with libvirt-java @efbe26d yielded this GDB output: (gdb) run ... 0x00007fffe7dfda14 in ffi_call_unix64 () from /usr/lib/x86_64-linux-gnu/libffi.so.6 Value returned is $1 = 0 (gdb) enable (gdb) c ... (gdb) memreport 1. @140737220921872 #1 testDomainGetSchedulerType testDomainGetSchedulerType /build/buildd/libvirt-0.9.12/./src/test/test_driver.c:2679 #2 virDomainGetSchedulerType virDomainGetSchedulerType /build/buildd/libvirt-0.9.12/./src/libvirt.c:6848 #3 ffi_call_unix64 ? ?:0 #4 ffi_call ? ?:0 #5 ... [1] #6 Java_com_sun_jna_Function_invokePointer ? ?:0 #7 ... [7]
In the meantime I pushed you initial patch, thanks !
Thank you! Evidently, this really fixed the memleak above. Yay! :) -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

At Thu, 11 Oct 2012 08:37:23 +0000, Benjamin Wang (gendwang) wrote:
Hi Claudio, Sorry for my late response. I have gone through Claudio's solution. It's good. But I think this is not a common solution. There are two points: 1. This solution must use Pointerbyreference to encapsulate the Pointer. This is not clean.
Yes, as I said, this adds another level of indirection --- which is pretty useless in Java.
2. Libvirt provides virFree method. But a common library could not provide memory management functions.
Sorry, I don't get your point here.
My proposal is as following: 1. Add a new Class Libc.java public interface Libc extends Library{ Libc INSTANCE = (Libc) Native.loadLibrary("c", Libc.class);
public void free(Pointer p); }
Not every platform has a shared library called "c". On Windows this would be msvcrt.dll for the Microsoft runtime. So, you would need to branch on the platform to load whatever library seems appropriate. Also, I just discovered that since version 3.3.0 JNA provides a public free method itself. Since I get crashes when using callback functions with JNA 3.2.7 in certain circumstances it is better just to require a newer version of JNA, IMHO. I'll post a few patches with improvements and memory fixes tomorrow. -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Hi Claudio, Thanks for you informing about new JNA version. I try to use JNA provided API. It works well. The updated code is as following: public SchedParameter[] getSchedulerParameters() throws LibvirtException { IntByReference nParams = new IntByReference(); SchedParameter[] returnValue = new SchedParameter[0]; - String scheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); + Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, + nParams); processError(); - if (scheduler != null) { + if (pScheduler != null) { + String scheduler = pScheduler.getString(0); + Native.free(Pointer.nativeValue(pScheduler)); virSchedParameter[] nativeParams = new virSchedParameter[nParams.getValue()]; returnValue = new SchedParameter[nParams.getValue()]; libvirt.virDomainGetSchedulerParameters(VDP, nativeParams, nParams); If there is no issue. I recommend to use this solution to enhance all JNA code. BTW: Not all the returned String should be freed by JNA. For example, In Domain Class, the result returned by the method getName/ getUUIDString can't be freed. Because the reference were not allocated temporarily. We must analyze case by case. B.R. Benjamin Wang -----Original Message----- From: Claudio Bley [mailto:cbley@av-test.de] Sent: 2012年10月11日 23:36 To: Benjamin Wang (gendwang) Cc: veillard@redhat.com; libvir-list@redhat.com; Yang Zhou (yangzho) Subject: Re: [libvirt] Memory free in libvirt JNA At Thu, 11 Oct 2012 08:37:23 +0000, Benjamin Wang (gendwang) wrote:
Hi Claudio, Sorry for my late response. I have gone through Claudio's solution. It's good. But I think this is not a common solution. There are two points: 1. This solution must use Pointerbyreference to encapsulate the Pointer. This is not clean.
Yes, as I said, this adds another level of indirection --- which is pretty useless in Java.
2. Libvirt provides virFree method. But a common library could not provide memory management functions.
Sorry, I don't get your point here.
My proposal is as following: 1. Add a new Class Libc.java public interface Libc extends Library{ Libc INSTANCE = (Libc) Native.loadLibrary("c", Libc.class);
public void free(Pointer p); }
Not every platform has a shared library called "c". On Windows this would be msvcrt.dll for the Microsoft runtime. So, you would need to branch on the platform to load whatever library seems appropriate. Also, I just discovered that since version 3.3.0 JNA provides a public free method itself. Since I get crashes when using callback functions with JNA 3.2.7 in certain circumstances it is better just to require a newer version of JNA, IMHO. I'll post a few patches with improvements and memory fixes tomorrow. -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Hi. / something went not quite right the last time, I'm resending this / / series. Please ignore my previous mails. / Just sending off a few patches that have piled up during the last few months. Patch #1 to #7 and #9 to #10 and #12 contain mostly cosmetic changes resp. changes to the build system. Patch #8 changes the handling of errors. It is unnecessary trying to retrieve an error when the libvirt function called did not signal any. Also, some functions never fail (return void). Patch #11 changes how errors are checked. This avoids copying and freeing an error object and hence a few JVM to native calls. Patch #13 fixes all the memory leaks I encountered by using my GDB memcheck.py script. Running the junit tests under GDB's supervision yielded 750 places of (potential) memory leaks, pointing to calls of these libvirt functions: virDomainDefineXML, virInterfaceGetXMLDesc, virConnectListDefinedDomains, virStoragePoolLookupByName, virDomainLookupByName, virNetworkGetBridgeName, virNetworkLookupByUUIDString, virDomainLookupByUUID, virDomainLookupByUUIDString, virConnectListInterfaces, virDomainGetOSType, virConnectListDefinedNetworks, virNetworkCreateXML, virStoragePoolDefineXML, virConnectOpen, virDomainCreateXML, virNetworkDefineXML, virNetworkLookupByName, virCopyLastError, virNetworkCreate, virNetworkLookupByUUID, virInterfaceLookupByName, virConnectGetHostname, virDomainGetXMLDesc, virConnectListNetworks, virNetworkGetXMLDesc After applying patch #13, the script reports this: 1. @140737220948192 #1 __GI___strdup __GI___strdup strdup.c:45 #2 ... [1] #3 Java_java_util_zip_ZipFile_open ? ?:0 #4 ... [5] 2. @140737221175744 #1 virAlloc virAlloc /build/buildd/libvirt-0.9.12/./src/util/memory.c:103 #2 virLastErrorObject virLastErrorObject /build/buildd/libvirt-0.9.12/./src/util/virterror.c:277 #3 virGetLastError virGetLastError /build/buildd/libvirt-0.9.12/./src/util/virterror.c:299 #4 ffi_call_unix64 ? ?:0 #5 ffi_call ? ?:0 #6 ... [1] #7 Java_com_sun_jna_Native_invokePointer ? ?:0 #8 ... [5] 3. @140737220736736 #1 __libc_res_nsend __libc_res_nsend res_send.c:442 #2 __libc_res_nquery __libc_res_nquery res_query.c:226 #3 __libc_res_nquerydomain __libc_res_nquerydomain res_query.c:578 #4 __libc_res_nsearch __libc_res_nsearch res_query.c:416 #5 _nss_dns_gethostbyname3_r _nss_dns_gethostbyname3_r nss_dns/dns-host.c:197 #6 gaih_inet gaih_inet ../sysdeps/posix/getaddrinfo.c:940 #7 __GI_getaddrinfo __GI_getaddrinfo ../sysdeps/posix/getaddrinfo.c:2423 #8 virGetHostname virGetHostname /build/buildd/libvirt-0.9.12/./src/util/util.c:2105 #9 virConnectGetHostname virConnectGetHostname /build/buildd/libvirt-0.9.12/./src/libvirt.c:1724 #10 ffi_call_unix64 ? ?:0 #11 ffi_call ? ?:0 #12 ... [1] #13 Java_com_sun_jna_Native_invokePointer ? ?:0 #14 ... [4] 4. @140737018598944 #1 virAlloc virAlloc /build/buildd/libvirt-0.9.12/./src/util/memory.c:103 #2 virLastErrorObject virLastErrorObject /build/buildd/libvirt-0.9.12/./src/util/virterror.c:277 #3 virResetLastError virResetLastError /build/buildd/libvirt-0.9.12/./src/util/virterror.c:428 #4 virNetworkFree virNetworkFree /build/buildd/libvirt-0.9.12/./src/libvirt.c:10151 #5 ffi_call_unix64 ? ?:0 #6 ffi_call ? ?:0 #7 ... [1] #8 Java_com_sun_jna_Native_invokeInt ? ?:0 #9 ... [2] 5. @140737221440624 #1 __libc_res_nsend __libc_res_nsend res_send.c:442 #2 __libc_res_nquery __libc_res_nquery res_query.c:226 #3 __libc_res_nquerydomain __libc_res_nquerydomain res_query.c:578 #4 __libc_res_nsearch __libc_res_nsearch res_query.c:416 #5 _nss_dns_gethostbyname3_r _nss_dns_gethostbyname3_r nss_dns/dns-host.c:197 #6 gaih_inet gaih_inet ../sysdeps/posix/getaddrinfo.c:940 #7 __GI_getaddrinfo __GI_getaddrinfo ../sysdeps/posix/getaddrinfo.c:2423 #8 virGetHostname virGetHostname /build/buildd/libvirt-0.9.12/./src/util/util.c:2105 #9 virConnectGetHostname virConnectGetHostname /build/buildd/libvirt-0.9.12/./src/libvirt.c:1724 #10 ffi_call_unix64 ? ?:0 #11 ffi_call ? ?:0 #12 ... [1] #13 Java_com_sun_jna_Native_invokePointer ? ?:0 #14 ... [4] only pointing to the following function calls: virConnectGetHostname, virNetworkFree, virGetLastError AFAICS, these are neglectable. Probably just some global memory which is not freed on exit. (for the record: I'm on Ubuntu Precise, using libvirt 0.9.12. And yes, I did call __libc_freeres on exit.) Patch #14 removes functions that should have never been wrapped. These functions do not increase the ref count and hence create Java objects that actually do not represent "real" instances on the libvirt side. I have tested with JNA 3.3.0, 3.4.{0, 1, 2}. I had JVM crashes repeatedly with all JNA versions before 3.4.2. So, I strongly recommend to use JNA 3.4.2. Claudio Bley (15): Explicitly set includeAntRuntime to false for javac tasks. Introduce a javac.debug property. Add findbugs build file for ant. Make finalize() methods protected. Remove redundant public modifier from Libvirt interface methods. Change visibility of class members to private to enforce encapsulation. Mark virConnCopyLastError and virConnGetLastError as deprecated. Call processError only if a libvirt function indicates an error. Split JUnit tests and use a fixture for Connect. Split "build" target and automatically rebuild out of date files. Avoid unnecessary copying and calling virResetLastError. Remove the libvirt instance attribute from all classes. Fix memory leaks for libvirt functions returning newly allocated memory. Remove functions not intended to be used by libvirt bindings. Explicitely define the order of a struct's fields. build.xml | 37 +- findbugs.xml | 36 ++ src/main/java/org/libvirt/Connect.java | 572 +++++++------------- src/main/java/org/libvirt/Device.java | 9 +- src/main/java/org/libvirt/Domain.java | 33 +- src/main/java/org/libvirt/DomainSnapshot.java | 9 +- src/main/java/org/libvirt/Error.java | 24 +- src/main/java/org/libvirt/ErrorHandler.java | 9 +- src/main/java/org/libvirt/Interface.java | 19 +- src/main/java/org/libvirt/Library.java | 88 +++ src/main/java/org/libvirt/LibvirtException.java | 2 +- src/main/java/org/libvirt/Network.java | 26 +- src/main/java/org/libvirt/NetworkFilter.java | 9 +- src/main/java/org/libvirt/Secret.java | 9 +- src/main/java/org/libvirt/StoragePool.java | 9 +- src/main/java/org/libvirt/StorageVol.java | 9 +- src/main/java/org/libvirt/Stream.java | 11 +- src/main/java/org/libvirt/jna/Libvirt.java | 502 ++++++++--------- src/main/java/org/libvirt/jna/virConnectAuth.java | 10 + .../java/org/libvirt/jna/virConnectCredential.java | 12 + .../java/org/libvirt/jna/virDomainBlockInfo.java | 8 + .../java/org/libvirt/jna/virDomainBlockStats.java | 11 + src/main/java/org/libvirt/jna/virDomainInfo.java | 11 + .../org/libvirt/jna/virDomainInterfaceStats.java | 13 + .../java/org/libvirt/jna/virDomainJobInfo.java | 18 + .../java/org/libvirt/jna/virDomainMemoryStats.java | 7 + src/main/java/org/libvirt/jna/virError.java | 19 + src/main/java/org/libvirt/jna/virNodeInfo.java | 15 + .../java/org/libvirt/jna/virSchedParameter.java | 9 + .../java/org/libvirt/jna/virStoragePoolInfo.java | 10 + .../java/org/libvirt/jna/virStorageVolInfo.java | 8 + src/main/java/org/libvirt/jna/virVcpuInfo.java | 9 + src/test/java/org/libvirt/TestJavaBindings.java | 50 +- src/test/java/org/libvirt/TestLibvirtGlobals.java | 21 + 34 files changed, 883 insertions(+), 761 deletions(-) create mode 100644 findbugs.xml create mode 100644 src/main/java/org/libvirt/Library.java create mode 100644 src/test/java/org/libvirt/TestLibvirtGlobals.java -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Use JNA's Native.free() method to free memory. This requires JNA version 3.3.0 or later. Remove virFree from Libvirt interface. --- src/main/java/org/libvirt/Connect.java | 109 ++++++++++++++++++---------- src/main/java/org/libvirt/Domain.java | 24 ++++-- src/main/java/org/libvirt/Interface.java | 10 ++- src/main/java/org/libvirt/Library.java | 62 ++++++++++++++++ src/main/java/org/libvirt/Network.java | 17 ++++- src/main/java/org/libvirt/jna/Libvirt.java | 37 +++++----- 6 files changed, 187 insertions(+), 72 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index ae306d6..a775ce1 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -19,6 +19,7 @@ import static org.libvirt.Library.libvirt; import com.sun.jna.Memory; import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; import com.sun.jna.ptr.LongByReference; /** @@ -510,8 +511,12 @@ public class Connect { * description</a> */ public String getCapabilities() throws LibvirtException { - String returnValue = libvirt.virConnectGetCapabilities(VCP); - return processError(returnValue); + Pointer ptr = processError(libvirt.virConnectGetCapabilities(VCP)); + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** @@ -545,7 +550,12 @@ public class Connect { * @throws LibvirtException */ public String getHostName() throws LibvirtException { - return processError(libvirt.virConnectGetHostname(VCP)); + Pointer ptr = processError(libvirt.virConnectGetHostname(VCP)); + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** @@ -701,11 +711,13 @@ public class Connect { */ public String[] listDefinedDomains() throws LibvirtException { int maxnames = numOfDefinedDomains(); - String[] names = new String[maxnames]; if (maxnames > 0) { - processError(libvirt.virConnectListDefinedDomains(VCP, names, maxnames)); + final Pointer[] names = new Pointer[maxnames]; + final int n = processError(libvirt.virConnectListDefinedDomains(VCP, names, maxnames)); + return Library.toStringArray(names, n); + } else { + return Library.NO_STRINGS; } - return names; } /** @@ -716,12 +728,14 @@ public class Connect { * @throws LibvirtException */ public String[] listDefinedInterfaces() throws LibvirtException { - int num = numOfDefinedInterfaces(); - String[] returnValue = new String[num]; - if (num > 0) { - processError(libvirt.virConnectListDefinedInterfaces(VCP, returnValue, num)); + final int max = numOfDefinedInterfaces(); + if (max > 0) { + final Pointer[] ifs = new Pointer[max]; + final int n = processError(libvirt.virConnectListDefinedInterfaces(VCP, ifs, max)); + return Library.toStringArray(ifs, n); + } else { + return Library.NO_STRINGS; } - return returnValue; } /** @@ -733,12 +747,13 @@ public class Connect { */ public String[] listDefinedNetworks() throws LibvirtException { int maxnames = numOfDefinedNetworks(); - String[] names = new String[maxnames]; - if (maxnames > 0) { - processError(libvirt.virConnectListDefinedNetworks(VCP, names, maxnames)); + final Pointer[] names = new Pointer[maxnames]; + final int n = processError(libvirt.virConnectListDefinedNetworks(VCP, names, maxnames)); + return Library.toStringArray(names, n); + } else { + return Library.NO_STRINGS; } - return names; } /** @@ -750,9 +765,13 @@ public class Connect { */ public String[] listDefinedStoragePools() throws LibvirtException { int num = numOfDefinedStoragePools(); - String[] returnValue = new String[num]; - processError(libvirt.virConnectListDefinedStoragePools(VCP, returnValue, num)); - return returnValue; + if (num > 0) { + Pointer[] pools = new Pointer[num]; + final int n = processError(libvirt.virConnectListDefinedStoragePools(VCP, pools, num)); + return Library.toStringArray(pools, n); + } else { + return Library.NO_STRINGS; + } } /** @@ -763,12 +782,13 @@ public class Connect { */ public String[] listDevices(String capabilityName) throws LibvirtException { int maxDevices = numOfDevices(capabilityName); - String[] names = new String[maxDevices]; - if (maxDevices > 0) { - processError(libvirt.virNodeListDevices(VCP, capabilityName, names, maxDevices, 0)); + Pointer[] names = new Pointer[maxDevices]; + final int n = processError(libvirt.virNodeListDevices(VCP, capabilityName, names, maxDevices, 0)); + return Library.toStringArray(names, n); + } else { + return Library.NO_STRINGS; } - return names; } /** @@ -796,11 +816,13 @@ public class Connect { */ public String[] listInterfaces() throws LibvirtException { int num = numOfInterfaces(); - String[] returnValue = new String[num]; if (num > 0) { - processError(libvirt.virConnectListInterfaces(VCP, returnValue, num)); + Pointer[] ifs = new Pointer[num]; + final int n = processError(libvirt.virConnectListInterfaces(VCP, ifs, num)); + return Library.toStringArray(ifs, n); + } else { + return Library.NO_STRINGS; } - return returnValue; } /** @@ -811,11 +833,13 @@ public class Connect { */ public String[] listNetworkFilters() throws LibvirtException { int maxnames = numOfNetworkFilters(); - String[] names = new String[maxnames]; if (maxnames > 0) { - processError(libvirt.virConnectListNWFilters(VCP, names, maxnames)); + Pointer[] names = new Pointer[maxnames]; + final int n = processError(libvirt.virConnectListNWFilters(VCP, names, maxnames)); + return Library.toStringArray(names, n); + } else { + return Library.NO_STRINGS; } - return names; } /** @@ -827,12 +851,13 @@ public class Connect { */ public String[] listNetworks() throws LibvirtException { int maxnames = numOfNetworks(); - String[] names = new String[maxnames]; - if (maxnames > 0) { - processError(libvirt.virConnectListNetworks(VCP, names, maxnames)); + Pointer[] names = new Pointer[maxnames]; + final int n = processError(libvirt.virConnectListNetworks(VCP, names, maxnames)); + return Library.toStringArray(names, n); + } else { + return Library.NO_STRINGS; } - return names; } /** @@ -843,9 +868,13 @@ public class Connect { */ public String[] listSecrets() throws LibvirtException { int num = numOfSecrets(); - String[] returnValue = new String[num]; - processError(libvirt.virConnectListSecrets(VCP, returnValue, num)); - return returnValue; + if (num > 0) { + Pointer[] returnValue = new Pointer[num]; + final int n = processError(libvirt.virConnectListSecrets(VCP, returnValue, num)); + return Library.toStringArray(returnValue, n); + } else { + return Library.NO_STRINGS; + } } /** @@ -857,9 +886,13 @@ public class Connect { */ public String[] listStoragePools() throws LibvirtException { int num = numOfStoragePools(); - String[] returnValue = new String[num]; - processError(libvirt.virConnectListStoragePools(VCP, returnValue, num)); - return returnValue; + if (num > 0) { + Pointer[] returnValue = new Pointer[num]; + final int n = processError(libvirt.virConnectListStoragePools(VCP, returnValue, num)); + return Library.toStringArray(returnValue, n); + } else { + return Library.NO_STRINGS; + } } /** diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 45fba26..1c86bd4 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -426,9 +426,13 @@ public class Domain { * @throws LibvirtException */ public String getOSType() throws LibvirtException { - String returnValue = libvirt.virDomainGetOSType(VDP); + Pointer ptr = libvirt.virDomainGetOSType(VDP); processError(); - return returnValue; + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** @@ -443,8 +447,8 @@ public class Domain { Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); if (pScheduler != null) { - String scheduler = pScheduler.getString(0); - libvirt.virFree(new PointerByReference(pScheduler)); + String scheduler = Library.getString(pScheduler); + Library.free(pScheduler); virSchedParameter[] nativeParams = new virSchedParameter[nParams.getValue()]; returnValue = new SchedParameter[nParams.getValue()]; libvirt.virDomainGetSchedulerParameters(VDP, nativeParams, nParams); @@ -472,8 +476,8 @@ public class Domain { Pointer pScheduler = libvirt.virDomainGetSchedulerType(VDP, nParams); processError(); String[] array = new String[1]; - array[0] = pScheduler.getString(0); - libvirt.virFree(new PointerByReference(pScheduler)); + array[0] = Library.getString(pScheduler); + Library.free(pScheduler); return array; } @@ -569,9 +573,13 @@ public class Domain { * Description format </a> */ public String getXMLDesc(int flags) throws LibvirtException { - String returnValue = libvirt.virDomainGetXMLDesc(VDP, flags); + Pointer ptr = libvirt.virDomainGetXMLDesc(VDP, flags); processError(); - return returnValue; + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** diff --git a/src/main/java/org/libvirt/Interface.java b/src/main/java/org/libvirt/Interface.java index 684adca..71ba3da 100644 --- a/src/main/java/org/libvirt/Interface.java +++ b/src/main/java/org/libvirt/Interface.java @@ -4,6 +4,8 @@ import org.libvirt.jna.InterfacePointer; import org.libvirt.jna.Libvirt; import static org.libvirt.Library.libvirt; +import com.sun.jna.Pointer; + /** * A device which is attached to a node */ @@ -113,9 +115,13 @@ public class Interface { * @throws LibvirtException */ public String getXMLDescription(int flags) throws LibvirtException { - String xml = libvirt.virInterfaceGetXMLDesc(VIP, flags); + Pointer xml = libvirt.virInterfaceGetXMLDesc(VIP, flags); processError(); - return xml; + try { + return Library.getString(xml); + } finally { + Library.free(xml); + } } /** diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java index 035ed06..0136095 100644 --- a/src/main/java/org/libvirt/Library.java +++ b/src/main/java/org/libvirt/Library.java @@ -2,15 +2,25 @@ package org.libvirt; import org.libvirt.jna.Libvirt; +import com.sun.jna.Native; +import com.sun.jna.Pointer; + /** * This class represents an instance of the JNA mapped libvirt * library. * * The library will get loaded when first accessing this class. + * + * Additionally, this class contains internal methods to ease + * implementing the public API. */ final class Library { final static Libvirt libvirt; + // an empty string array constant + // prefer this over creating empty arrays dynamically. + final static String[] NO_STRINGS = {}; + // Load the native part static { Libvirt.INSTANCE.virInitialize(); @@ -23,4 +33,56 @@ final class Library { } private Library() {} + + /** + * Free memory pointed to by ptr. + */ + static void free(Pointer ptr) { + Native.free(Pointer.nativeValue(ptr)); + Pointer.nativeValue(ptr, 0L); + } + + /** + * Convert the data pointed to by {@code ptr} to a String. + */ + static String getString(Pointer ptr) { + final long len = ptr.indexOf(0, (byte)0); + assert (len != -1): "C-Strings must be \\0 terminated."; + + final byte[] data = ptr.getByteArray(0, (int)len); + try { + return new String(data, "utf-8"); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException("Libvirt problem: UTF-8 decoding error.", e); + } + } + + /** + * Calls {@link #toStringArray(Pointer[], int)}. + */ + static String[] toStringArray(Pointer[] ptrArr) { + return toStringArray(ptrArr, ptrArr.length); + } + + /** + * Convert the given array of native pointers to "char" in + * UTF-8 encoding to an array of Strings. + * + * \note The memory used by the elements of the original array + * is freed and ptrArr is modified. + */ + static String[] toStringArray(Pointer[] ptrArr, final int size) { + try { + final String[] result = new String[size]; + for (int i = 0; i < size; ++i) { + result[i] = Library.getString(ptrArr[i]); + } + return result; + } finally { + for (int i = 0; i < size; ++i) { + Library.free(ptrArr[i]); + ptrArr[i] = null; + } + } + } } diff --git a/src/main/java/org/libvirt/Network.java b/src/main/java/org/libvirt/Network.java index bdb0d78..2244c5d 100644 --- a/src/main/java/org/libvirt/Network.java +++ b/src/main/java/org/libvirt/Network.java @@ -5,6 +5,7 @@ import org.libvirt.jna.NetworkPointer; import static org.libvirt.Library.libvirt; import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; /** @@ -105,9 +106,13 @@ public class Network { * @throws LibvirtException */ public String getBridgeName() throws LibvirtException { - String returnValue = libvirt.virNetworkGetBridgeName(VNP); + final Pointer ptr = libvirt.virNetworkGetBridgeName(VNP); processError(); - return returnValue; + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** @@ -178,9 +183,13 @@ public class Network { * @throws LibvirtException */ public String getXMLDesc(int flags) throws LibvirtException { - String returnValue = libvirt.virNetworkGetXMLDesc(VNP, flags); + Pointer ptr = libvirt.virNetworkGetXMLDesc(VNP, flags); processError(); - return returnValue; + try { + return Library.getString(ptr); + } finally { + Library.free(ptr); + } } /** diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index be0de3b..5d2a291 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -56,9 +56,6 @@ import com.sun.jna.ptr.PointerByReference; * */ public interface Libvirt extends Library { - // Memory management - void virFree(PointerByReference ptr); - // Callbacks /** * Callback interface for authorization @@ -126,23 +123,23 @@ public interface Libvirt extends Library { int virConnectIsEncrypted(ConnectionPointer virConnectPtr) ; int virConnectIsSecure(ConnectionPointer virConnectPtr) ; String virConnectFindStoragePoolSources(ConnectionPointer virConnectPtr, String type, String srcSpec, int flags); - String virConnectGetCapabilities(ConnectionPointer virConnectPtr); - String virConnectGetHostname(ConnectionPointer virConnectPtr); + Pointer virConnectGetCapabilities(ConnectionPointer virConnectPtr); + Pointer virConnectGetHostname(ConnectionPointer virConnectPtr); int virConnectGetLibVersion(ConnectionPointer virConnectPtr, LongByReference libVer); int virConnectGetMaxVcpus(ConnectionPointer virConnectPtr, String type); String virConnectGetType(ConnectionPointer virConnectPtr); String virConnectGetURI(ConnectionPointer virConnectPtr); int virConnectGetVersion(ConnectionPointer virConnectPtr, LongByReference hvVer); - int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, String[] name, int maxnames); - int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); - int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); - int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); + int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); + int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); + int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, Pointer[] names, int maxnames); + int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, Pointer[] name, int maxNames); int virConnectListDomains(ConnectionPointer virConnectPtr, int[] ids, int maxnames); - int virConnectListInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); - int virConnectListNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); - int virConnectListNWFilters(ConnectionPointer virConnectPtr, String[] name, int maxnames); - int virConnectListSecrets(ConnectionPointer virConnectPtr, String[] uids, int maxUids); - int virConnectListStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); + int virConnectListInterfaces(ConnectionPointer virConnectPtr, Pointer[] name, int maxNames); + int virConnectListNetworks(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); + int virConnectListNWFilters(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); + int virConnectListSecrets(ConnectionPointer virConnectPtr, Pointer[] uids, int maxUids); + int virConnectListStoragePools(ConnectionPointer virConnectPtr, Pointer[] names, int maxnames); int virConnectNumOfDefinedDomains(ConnectionPointer virConnectPtr); int virConnectNumOfDefinedNetworks(ConnectionPointer virConnectPtr); int virConnectNumOfDefinedInterfaces(ConnectionPointer virConnectPtr); @@ -203,14 +200,14 @@ public interface Libvirt extends Library { NativeLong virDomainGetMaxMemory(DomainPointer virDomainPtr); int virDomainGetMaxVcpus(DomainPointer virDomainPtr); String virDomainGetName(DomainPointer virDomainPtr); - String virDomainGetOSType(DomainPointer virDomainPtr); + Pointer virDomainGetOSType(DomainPointer virDomainPtr); int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, IntByReference nparams); Pointer virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); int virDomainGetUUID(DomainPointer virDomainPtr, byte[] uuidString); int virDomainGetUUIDString(DomainPointer virDomainPtr, byte[] uuidString); int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, int maxInfo, byte[] cpumaps, int maplen); - String virDomainGetXMLDesc(DomainPointer virDomainPtr, int flags); + Pointer virDomainGetXMLDesc(DomainPointer virDomainPtr, int flags); int virDomainHasCurrentSnapshot(DomainPointer virDomainPtr, int flags); int virDomainHasManagedSaveImage(DomainPointer virDomainPtr, int flags); int virDomainInterfaceStats(DomainPointer virDomainPtr, String path, virDomainInterfaceStats stats, int size); @@ -252,11 +249,11 @@ public interface Libvirt extends Library { int virNetworkDestroy(NetworkPointer virConnectPtr); int virNetworkFree(NetworkPointer virConnectPtr); int virNetworkGetAutostart(NetworkPointer virNetworkPtr, IntByReference value); - String virNetworkGetBridgeName(NetworkPointer virNetworkPtr); + Pointer virNetworkGetBridgeName(NetworkPointer virNetworkPtr); String virNetworkGetName(NetworkPointer virNetworkPtr); int virNetworkGetUUID(NetworkPointer virNetworkPtr, byte[] uuidString); int virNetworkGetUUIDString(NetworkPointer virNetworkPtr, byte[] uuidString); - String virNetworkGetXMLDesc(NetworkPointer virNetworkPtr, int flags); + Pointer virNetworkGetXMLDesc(NetworkPointer virNetworkPtr, int flags); int virNetworkIsActive(NetworkPointer virNetworkPtr); int virNetworkIsPersistent(NetworkPointer virNetworkPtr); NetworkPointer virNetworkLookupByName(ConnectionPointer virConnectPtr, String name); @@ -273,7 +270,7 @@ public interface Libvirt extends Library { // Node/Device functions int virNodeNumOfDevices(ConnectionPointer virConnectPtr, String capabilityName, int flags); - int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, String[] names, int maxnames, + int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, Pointer[] names, int maxnames, int flags); DevicePointer virNodeDeviceLookupByName(ConnectionPointer virConnectPtr, String name); String virNodeDeviceGetName(DevicePointer virDevicePointer); @@ -337,7 +334,7 @@ public interface Libvirt extends Library { int virInterfaceFree(InterfacePointer virDevicePointer); String virInterfaceGetName(InterfacePointer virInterfacePtr); String virInterfaceGetMACString(InterfacePointer virInterfacePtr); - String virInterfaceGetXMLDesc(InterfacePointer virInterfacePtr, int flags); + Pointer virInterfaceGetXMLDesc(InterfacePointer virInterfacePtr, int flags); int virInterfaceIsActive(InterfacePointer virDevicePointer); InterfacePointer virInterfaceLookupByMACString(ConnectionPointer virConnectPtr, String mac); InterfacePointer virInterfaceLookupByName(ConnectionPointer virConnectPtr, String name); -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

This affects virSecretGetConnect, virNetworkGetConnect and virDomainGetConnect. The libvirt API documentation has this to say about those functions: WARNING: When writing libvirt bindings in other languages, do not use this function. Instead, store the connection and the ... object together. --- src/main/java/org/libvirt/Connect.java | 39 ----------------------- src/main/java/org/libvirt/jna/Libvirt.java | 3 -- src/test/java/org/libvirt/TestJavaBindings.java | 3 -- 3 files changed, 45 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index a775ce1..b3e29be 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -31,45 +31,6 @@ import com.sun.jna.ptr.LongByReference; public class Connect { /** - * Creates a new connection object from the domain. If all you want is the - * existing domain's connection, use the getConnection method directly. Thie - * method returns a new connection. - * - * @param domain - * @return a new connection - */ - public static Connect connectionForDomain(Domain domain) { - ConnectionPointer conn = Libvirt.INSTANCE.virDomainGetConnect(domain.VDP); - return new Connect(conn); - } - - /** - * Creates a new connection object from the network. If all you want is the - * existing network's connection, use the getConnection method directly. - * Thie method returns a new connection. - * - * @param network - * @return a new connection - */ - public static Connect connectionForNetwork(Network network) { - ConnectionPointer conn = Libvirt.INSTANCE.virNetworkGetConnect(network.VNP); - return new Connect(conn); - } - - /** - * Creates a new connection object from the network. If all you want is the - * existing network's connection, use the getConnection method directly. - * Thie method returns a new connection. - * - * @param secret - * @return a new connection - */ - public static Connect connectionForSecret(Secret secret) { - ConnectionPointer conn = Libvirt.INSTANCE.virSecretGetConnect(secret.VSP); - return new Connect(conn); - } - - /** * Get the version of a connection. * * @see <a diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index 5d2a291..87979cd 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -192,7 +192,6 @@ public interface Libvirt extends Library { int virDomainDetachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); int virDomainFree(DomainPointer virDomainPtr); int virDomainGetAutostart(DomainPointer virDomainPtr, IntByReference value); - ConnectionPointer virDomainGetConnect(DomainPointer virDomainPtr); int virDomainGetBlockInfo(DomainPointer virDomainPtr, String path, virDomainBlockInfo info, int flags); int virDomainGetID(DomainPointer virDomainPtr); int virDomainGetInfo(DomainPointer virDomainPtr, virDomainInfo vInfo); @@ -242,7 +241,6 @@ public interface Libvirt extends Library { int virDomainUndefine(DomainPointer virDomainPtr); // Network functions - ConnectionPointer virNetworkGetConnect(NetworkPointer virnetworkPtr); int virNetworkCreate(NetworkPointer virConnectPtr); NetworkPointer virNetworkCreateXML(ConnectionPointer virConnectPtr, String xmlDesc); NetworkPointer virNetworkDefineXML(ConnectionPointer virConnectPtr, String xmlDesc); @@ -341,7 +339,6 @@ public interface Libvirt extends Library { int virInterfaceUndefine(InterfacePointer virDevicePointer); // Secret Methods - ConnectionPointer virSecretGetConnect(SecretPointer virSecretPtr); int virSecretFree(SecretPointer virSecretPtr); SecretPointer virSecretDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); int virSecretGetUUID(SecretPointer virSecretPtr, byte[] uuidString); diff --git a/src/test/java/org/libvirt/TestJavaBindings.java b/src/test/java/org/libvirt/TestJavaBindings.java index 55ca64b..bba4cdb 100644 --- a/src/test/java/org/libvirt/TestJavaBindings.java +++ b/src/test/java/org/libvirt/TestJavaBindings.java @@ -158,9 +158,6 @@ public final class TestJavaBindings extends TestCase { dom.setSchedulerParameters(pars); dom.getSchedulerParameters() ; - - assertNotNull(Connect.connectionForDomain(dom)); - assertTrue(Connect.connectionForDomain(dom) != dom.getConnect()); } public void testInterfaces() throws Exception { -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

The latest JNA version requires us to define the order of the fields in a struct explicitely because the JVM does not guarantee the order of the fields returned by Class.getFields(). --- src/main/java/org/libvirt/jna/virConnectAuth.java | 10 ++++++++++ .../java/org/libvirt/jna/virConnectCredential.java | 12 ++++++++++++ .../java/org/libvirt/jna/virDomainBlockInfo.java | 8 ++++++++ .../java/org/libvirt/jna/virDomainBlockStats.java | 11 +++++++++++ src/main/java/org/libvirt/jna/virDomainInfo.java | 11 +++++++++++ .../org/libvirt/jna/virDomainInterfaceStats.java | 13 +++++++++++++ .../java/org/libvirt/jna/virDomainJobInfo.java | 18 ++++++++++++++++++ .../java/org/libvirt/jna/virDomainMemoryStats.java | 7 +++++++ src/main/java/org/libvirt/jna/virError.java | 19 +++++++++++++++++++ src/main/java/org/libvirt/jna/virNodeInfo.java | 15 +++++++++++++++ .../java/org/libvirt/jna/virSchedParameter.java | 9 +++++++++ .../java/org/libvirt/jna/virStoragePoolInfo.java | 10 ++++++++++ .../java/org/libvirt/jna/virStorageVolInfo.java | 8 ++++++++ src/main/java/org/libvirt/jna/virVcpuInfo.java | 9 +++++++++ 14 files changed, 160 insertions(+) diff --git a/src/main/java/org/libvirt/jna/virConnectAuth.java b/src/main/java/org/libvirt/jna/virConnectAuth.java index 74dd65c..f805b89 100644 --- a/src/main/java/org/libvirt/jna/virConnectAuth.java +++ b/src/main/java/org/libvirt/jna/virConnectAuth.java @@ -3,6 +3,9 @@ package org.libvirt.jna; import com.sun.jna.Pointer; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virConnectAuth structure */ @@ -11,4 +14,11 @@ public class virConnectAuth extends Structure { public int ncredtype; public Libvirt.VirConnectAuthCallback cb; public Pointer cbdata; + + protected List getFieldOrder() { + return Arrays.asList("credtype", + "ncredtype", + "cb", + "cbdata"); + } } diff --git a/src/main/java/org/libvirt/jna/virConnectCredential.java b/src/main/java/org/libvirt/jna/virConnectCredential.java index ba47482..7a750d1 100644 --- a/src/main/java/org/libvirt/jna/virConnectCredential.java +++ b/src/main/java/org/libvirt/jna/virConnectCredential.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virConnectCredential structure */ @@ -13,4 +16,13 @@ public class virConnectCredential extends Structure implements Structure.ByRefer // public Pointer result; public String result; public int resultlen; + + protected List getFieldOrder() { + return Arrays.asList("type", + "prompt", + "challenge", + "defresult", + "result", + "resultlen"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainBlockInfo.java b/src/main/java/org/libvirt/jna/virDomainBlockInfo.java index 234a381..fdf8bb1 100644 --- a/src/main/java/org/libvirt/jna/virDomainBlockInfo.java +++ b/src/main/java/org/libvirt/jna/virDomainBlockInfo.java @@ -2,9 +2,17 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + public class virDomainBlockInfo extends Structure { public long capacity; public long allocation; public long physical; + protected List getFieldOrder() { + return Arrays.asList("capacity", + "allocation", + "physical"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainBlockStats.java b/src/main/java/org/libvirt/jna/virDomainBlockStats.java index f29dba0..c7f0d8c 100644 --- a/src/main/java/org/libvirt/jna/virDomainBlockStats.java +++ b/src/main/java/org/libvirt/jna/virDomainBlockStats.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virDomainBlockStats structure */ @@ -16,4 +19,12 @@ public class virDomainBlockStats extends Structure { // is correct public long errs; // this is a long long in the code, so a long mapping is // correct + + protected List getFieldOrder() { + return Arrays.asList("rd_req", + "rd_bytes", + "wr_req", + "wr_bytes", + "errs"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainInfo.java b/src/main/java/org/libvirt/jna/virDomainInfo.java index a93c0a5..8525f37 100644 --- a/src/main/java/org/libvirt/jna/virDomainInfo.java +++ b/src/main/java/org/libvirt/jna/virDomainInfo.java @@ -3,6 +3,9 @@ package org.libvirt.jna; import com.sun.jna.NativeLong; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virDomainInfo structure */ @@ -12,4 +15,12 @@ public class virDomainInfo extends Structure { public NativeLong memory; public short nrVirtCpu; public long cpuTime; + + protected List getFieldOrder() { + return Arrays.asList("state", + "maxMem", + "memory", + "nrVirtCpu", + "cpuTime"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainInterfaceStats.java b/src/main/java/org/libvirt/jna/virDomainInterfaceStats.java index 1cb0e66..39ceb52 100644 --- a/src/main/java/org/libvirt/jna/virDomainInterfaceStats.java +++ b/src/main/java/org/libvirt/jna/virDomainInterfaceStats.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virDomainInterfaceStats structure */ @@ -23,4 +26,14 @@ public class virDomainInterfaceStats extends Structure { public long tx_drop; // this is a long long in the code, so a long mapping // is correct + protected List getFieldOrder() { + return Arrays.asList("rx_bytes", + "rx_packets", + "rx_errs", + "rx_drop", + "tx_bytes", + "tx_packets", + "tx_errs", + "tx_drop"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainJobInfo.java b/src/main/java/org/libvirt/jna/virDomainJobInfo.java index 98b4f59..f8b63e0 100644 --- a/src/main/java/org/libvirt/jna/virDomainJobInfo.java +++ b/src/main/java/org/libvirt/jna/virDomainJobInfo.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + public class virDomainJobInfo extends Structure { public int type; public long timeElapsed; @@ -15,4 +18,19 @@ public class virDomainJobInfo extends Structure { public long fileTotal; public long fileProcessed; public long fileRemaining; + + protected List getFieldOrder() { + return Arrays.asList("type", + "timeElapsed", + "timeRemaining", + "dataTotal", + "dataProcessed", + "dataRemaining", + "memTotal", + "memProcessed", + "memRemaining", + "fileTotal", + "fileProcessed", + "fileRemaining"); + } } diff --git a/src/main/java/org/libvirt/jna/virDomainMemoryStats.java b/src/main/java/org/libvirt/jna/virDomainMemoryStats.java index 7a9f5d2..1d4e075 100644 --- a/src/main/java/org/libvirt/jna/virDomainMemoryStats.java +++ b/src/main/java/org/libvirt/jna/virDomainMemoryStats.java @@ -2,7 +2,14 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + public class virDomainMemoryStats extends Structure { public int tag ; public long val ; + + protected List getFieldOrder() { + return Arrays.asList("tag", "val"); + } } diff --git a/src/main/java/org/libvirt/jna/virError.java b/src/main/java/org/libvirt/jna/virError.java index e2580dd..b3fad6d 100644 --- a/src/main/java/org/libvirt/jna/virError.java +++ b/src/main/java/org/libvirt/jna/virError.java @@ -3,6 +3,9 @@ package org.libvirt.jna; import com.sun.jna.Pointer; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virError structure */ @@ -19,4 +22,20 @@ public class virError extends Structure { public int int1; public int int2; public NetworkPointer net; + + protected List getFieldOrder() { + return Arrays.asList( + "code", + "domain", + "message", + "level", + "conn", + "dom", + "str1", + "str2", + "str3", + "int1", + "int2", + "net"); + } } diff --git a/src/main/java/org/libvirt/jna/virNodeInfo.java b/src/main/java/org/libvirt/jna/virNodeInfo.java index 532aad9..6f0d002 100644 --- a/src/main/java/org/libvirt/jna/virNodeInfo.java +++ b/src/main/java/org/libvirt/jna/virNodeInfo.java @@ -3,6 +3,9 @@ package org.libvirt.jna; import com.sun.jna.NativeLong; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virNodeInfo structure */ @@ -21,4 +24,16 @@ public class virNodeInfo extends Structure { public int sockets; public int cores; public int threads; + + protected List getFieldOrder() { + return Arrays.asList( + "model", + "memory", + "cpus", + "mhz", + "nodes", + "sockets", + "cores", + "threads"); + } } \ No newline at end of file diff --git a/src/main/java/org/libvirt/jna/virSchedParameter.java b/src/main/java/org/libvirt/jna/virSchedParameter.java index 0013fff..e213f04 100644 --- a/src/main/java/org/libvirt/jna/virSchedParameter.java +++ b/src/main/java/org/libvirt/jna/virSchedParameter.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virSchedParameter structure */ @@ -9,4 +12,10 @@ public class virSchedParameter extends Structure { public byte field[] = new byte[Libvirt.VIR_DOMAIN_SCHED_FIELD_LENGTH]; public int type; public virSchedParameterValue value; + + protected List getFieldOrder() { + return Arrays.asList("field", + "type", + "value"); + } } diff --git a/src/main/java/org/libvirt/jna/virStoragePoolInfo.java b/src/main/java/org/libvirt/jna/virStoragePoolInfo.java index 5a98e08..860b78e 100644 --- a/src/main/java/org/libvirt/jna/virStoragePoolInfo.java +++ b/src/main/java/org/libvirt/jna/virStoragePoolInfo.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virStoragePoolInfo structure */ @@ -13,4 +16,11 @@ public class virStoragePoolInfo extends Structure { // mapping is correct public long available; // this is a long long in the code, so a long mapping // is correct + + protected List getFieldOrder() { + return Arrays.asList("state", + "capacity", + "allocation", + "available"); + } } diff --git a/src/main/java/org/libvirt/jna/virStorageVolInfo.java b/src/main/java/org/libvirt/jna/virStorageVolInfo.java index db8a5bd..d07b22e 100644 --- a/src/main/java/org/libvirt/jna/virStorageVolInfo.java +++ b/src/main/java/org/libvirt/jna/virStorageVolInfo.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virStorageVolInfo structure */ @@ -12,4 +15,9 @@ public class virStorageVolInfo extends Structure { public long allocation; // this is a long long in the code, so a long // mapping is correct + protected List getFieldOrder() { + return Arrays.asList("type", + "capacity", + "allocation"); + } } \ No newline at end of file diff --git a/src/main/java/org/libvirt/jna/virVcpuInfo.java b/src/main/java/org/libvirt/jna/virVcpuInfo.java index 16f237d..7bf3448 100644 --- a/src/main/java/org/libvirt/jna/virVcpuInfo.java +++ b/src/main/java/org/libvirt/jna/virVcpuInfo.java @@ -2,6 +2,9 @@ package org.libvirt.jna; import com.sun.jna.Structure; +import java.util.List; +import java.util.Arrays; + /** * JNA mapping for the virVcpuInfo structure */ @@ -12,4 +15,10 @@ public class virVcpuInfo extends Structure { // is correct public int cpu; + protected List getFieldOrder() { + return Arrays.asList("number", + "state", + "cpuTime", + "cpu"); + } } -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Set this to 'true' if you want to build your .class files with debug information. --- build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build.xml b/build.xml index 158a8a5..0b147b0 100644 --- a/build.xml +++ b/build.xml @@ -13,6 +13,7 @@ <property name="debian.controlfile" value="${debian.pkgdir}/DEBIAN/control" /> <property name="debian.pkg" value="target/libvirt-java_${version}_all.deb" /> <property environment="env"/> + <property name="javac.debug" value="off" /> <path id="compile.classpath"> <fileset dir="${jar.dir}"> -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Reported by findbugs: Finalizer should be protected, not public A class's finalize() method should have protected access, not public. Bug kind and pattern: FI - FI_PUBLIC_SHOULD_BE_PROTECTED --- src/main/java/org/libvirt/Connect.java | 2 +- src/main/java/org/libvirt/Device.java | 2 +- src/main/java/org/libvirt/Domain.java | 2 +- src/main/java/org/libvirt/DomainSnapshot.java | 2 +- src/main/java/org/libvirt/Interface.java | 2 +- src/main/java/org/libvirt/Network.java | 2 +- src/main/java/org/libvirt/NetworkFilter.java | 2 +- src/main/java/org/libvirt/Secret.java | 2 +- src/main/java/org/libvirt/StoragePool.java | 2 +- src/main/java/org/libvirt/StorageVol.java | 2 +- src/main/java/org/libvirt/Stream.java | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 0a94976..5419e85 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -533,7 +533,7 @@ public class Connect { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { close(); } diff --git a/src/main/java/org/libvirt/Device.java b/src/main/java/org/libvirt/Device.java index 8a52e81..bc25258 100644 --- a/src/main/java/org/libvirt/Device.java +++ b/src/main/java/org/libvirt/Device.java @@ -68,7 +68,7 @@ public class Device { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index fc1f665..f4f5225 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -284,7 +284,7 @@ public class Domain { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/DomainSnapshot.java b/src/main/java/org/libvirt/DomainSnapshot.java index add6830..3083ca0 100644 --- a/src/main/java/org/libvirt/DomainSnapshot.java +++ b/src/main/java/org/libvirt/DomainSnapshot.java @@ -49,7 +49,7 @@ public class DomainSnapshot { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/Interface.java b/src/main/java/org/libvirt/Interface.java index 1ae8b94..17c189d 100644 --- a/src/main/java/org/libvirt/Interface.java +++ b/src/main/java/org/libvirt/Interface.java @@ -68,7 +68,7 @@ public class Interface { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/Network.java b/src/main/java/org/libvirt/Network.java index 9684cb4..acaef0e 100644 --- a/src/main/java/org/libvirt/Network.java +++ b/src/main/java/org/libvirt/Network.java @@ -65,7 +65,7 @@ public class Network { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/NetworkFilter.java b/src/main/java/org/libvirt/NetworkFilter.java index 016cf1a..7bc07a5 100644 --- a/src/main/java/org/libvirt/NetworkFilter.java +++ b/src/main/java/org/libvirt/NetworkFilter.java @@ -28,7 +28,7 @@ public class NetworkFilter { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/Secret.java b/src/main/java/org/libvirt/Secret.java index febd75b..888cdf3 100644 --- a/src/main/java/org/libvirt/Secret.java +++ b/src/main/java/org/libvirt/Secret.java @@ -36,7 +36,7 @@ public class Secret { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/StoragePool.java b/src/main/java/org/libvirt/StoragePool.java index 0328d8c..29a18ed 100644 --- a/src/main/java/org/libvirt/StoragePool.java +++ b/src/main/java/org/libvirt/StoragePool.java @@ -116,7 +116,7 @@ public class StoragePool { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/StorageVol.java b/src/main/java/org/libvirt/StorageVol.java index 1bed6e1..e2bc717 100644 --- a/src/main/java/org/libvirt/StorageVol.java +++ b/src/main/java/org/libvirt/StorageVol.java @@ -76,7 +76,7 @@ public class StorageVol { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } diff --git a/src/main/java/org/libvirt/Stream.java b/src/main/java/org/libvirt/Stream.java index 6374567..0056a78 100644 --- a/src/main/java/org/libvirt/Stream.java +++ b/src/main/java/org/libvirt/Stream.java @@ -61,7 +61,7 @@ public class Stream { } @Override - public void finalize() throws LibvirtException { + protected void finalize() throws LibvirtException { free(); } -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

--- src/main/java/org/libvirt/Error.java | 24 +++++++++++------------ src/main/java/org/libvirt/LibvirtException.java | 2 +- src/main/java/org/libvirt/Stream.java | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/libvirt/Error.java b/src/main/java/org/libvirt/Error.java index e3c3246..114e758 100644 --- a/src/main/java/org/libvirt/Error.java +++ b/src/main/java/org/libvirt/Error.java @@ -199,18 +199,18 @@ public class Error implements Serializable { */ private static final long serialVersionUID = -4780109197014633842L; - ErrorNumber code; - ErrorDomain domain; - String message; - ErrorLevel level; - ConnectionPointer VCP; /* Deprecated */ - DomainPointer VDP; /* Deprecated */ - String str1; - String str2; - String str3; - int int1; - int int2; - NetworkPointer VNP; /* Deprecated */ + private ErrorNumber code; + private ErrorDomain domain; + private String message; + private ErrorLevel level; + private ConnectionPointer VCP; /* Deprecated */ + private DomainPointer VDP; /* Deprecated */ + private String str1; + private String str2; + private String str3; + private int int1; + private int int2; + private NetworkPointer VNP; /* Deprecated */ public Error(virError vError) { code = code.wrap(vError.code); diff --git a/src/main/java/org/libvirt/LibvirtException.java b/src/main/java/org/libvirt/LibvirtException.java index 5bd2d6e..f9546be 100644 --- a/src/main/java/org/libvirt/LibvirtException.java +++ b/src/main/java/org/libvirt/LibvirtException.java @@ -11,7 +11,7 @@ public class LibvirtException extends Exception { private static final long serialVersionUID = 5566904363426773529L; - Error virError; + private Error virError; LibvirtException(Error virError) { super(virError.getMessage()); diff --git a/src/main/java/org/libvirt/Stream.java b/src/main/java/org/libvirt/Stream.java index 0056a78..06b67cf 100644 --- a/src/main/java/org/libvirt/Stream.java +++ b/src/main/java/org/libvirt/Stream.java @@ -12,7 +12,7 @@ public class Stream { /** * the native virStreamPtr. */ - StreamPointer VSP; + private StreamPointer VSP; /** * The Connect Object that represents the Hypervisor of this Domain -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

They are only retained for backwards compatibility. --- src/main/java/org/libvirt/jna/Libvirt.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index 02457b7..be0de3b 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -109,6 +109,14 @@ public interface Libvirt extends Library { // Connection Functions String virConnectBaselineCPU(ConnectionPointer virConnectPtr, String[] xmlCPUs, int ncpus, int flags); + + /** + * @deprecated as of libvirt 0.6.0, all errors reported in the + * per-connection object are also duplicated in the global error + * object. This method remains for backwards compatibility. Use + * {@link #virCopyLastError} instead. + */ + @Deprecated int virConnCopyLastError(ConnectionPointer virConnectPtr, virError to); int virConnectClose(ConnectionPointer virConnectPtr); int virConnectCompareCPU(ConnectionPointer virConnectPtr, String xmlDesc, int flags); @@ -148,6 +156,14 @@ public interface Libvirt extends Library { ConnectionPointer virConnectOpen(String name); ConnectionPointer virConnectOpenAuth(String name, virConnectAuth auth, int flags); ConnectionPointer virConnectOpenReadOnly(String name); + + /** + * @deprecated as of libvirt 0.6.0, all errors reported in the + * per-connection object are also duplicated in the global error + * object. This method remains only for backwards compatibility. + * Use {@link #virGetLastError} instead. + */ + @Deprecated virError virConnGetLastError(ConnectionPointer virConnectPtr); int virConnResetLastError(ConnectionPointer virConnectPtr); String virConnectDomainXMLFromNative(ConnectionPointer virConnectPtr, String nativeFormat, -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Usually, when libvirt functions return an int, an error is indicated by returning -1. If libvirt functions return an object (pointer), an error is indicated by returning null. Add overloads for method processError that check for these special return values and call processError() in case an error occurred. --- src/main/java/org/libvirt/Connect.java | 430 ++++++++++---------------------- 1 file changed, 135 insertions(+), 295 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 5419e85..e02c601 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -170,7 +170,7 @@ public class Connect { public Connect(String uri) throws LibvirtException { VCP = libvirt.virConnectOpen(uri); // Check for an error - processError(); + processError(VCP); ErrorHandler.processError(Libvirt.INSTANCE); } @@ -191,7 +191,7 @@ public class Connect { VCP = libvirt.virConnectOpen(uri); } // Check for an error - processError(); + processError(VCP); ErrorHandler.processError(Libvirt.INSTANCE); } @@ -224,7 +224,7 @@ public class Connect { VCP = libvirt.virConnectOpenAuth(uri, vAuth, flags); // Check for an error - processError(); + processError(VCP); ErrorHandler.processError(Libvirt.INSTANCE); } @@ -238,9 +238,7 @@ public class Connect { * @throws LibvirtException */ public String baselineCPU(String[] xmlCPUs) throws LibvirtException { - String returnValue = libvirt.virConnectBaselineCPU(VCP, xmlCPUs, xmlCPUs.length, 0); - processError(); - return returnValue; + return processError(libvirt.virConnectBaselineCPU(VCP, xmlCPUs, xmlCPUs.length, 0)); } /** @@ -248,20 +246,19 @@ public class Connect { * the object after close() will result in an exception. * * @throws LibvirtException - * @return number of references left (>= 0) for success, -1 for failure. + * @return number of remaining references (>= 0) */ public int close() throws LibvirtException { int success = 0; if (VCP != null) { success = libvirt.virConnectClose(VCP); - processError(); // If leave an invalid pointer dangling around JVM crashes and burns // if someone tries to call a method on us // We rely on the underlying libvirt error handling to detect that // it's called with a null virConnectPointer VCP = null; } - return success; + return processError(success); } /** @@ -290,13 +287,8 @@ public class Connect { * @throws LibvirtException */ public Device deviceCreateXML(String xmlDesc) throws LibvirtException { - Device returnValue = null; - DevicePointer ptr = libvirt.virNodeDeviceCreateXML(VCP, xmlDesc, 0); - processError(); - if (ptr != null) { - returnValue = new Device(this, ptr); - } - return returnValue; + DevicePointer ptr = processError(libvirt.virNodeDeviceCreateXML(VCP, xmlDesc, 0)); + return new Device(this, ptr); } /** @@ -308,8 +300,7 @@ public class Connect { * @throws LibvirtException */ public Device deviceLookupByName(String name) throws LibvirtException { - DevicePointer ptr = libvirt.virNodeDeviceLookupByName(VCP, name); - processError(); + DevicePointer ptr = processError(libvirt.virNodeDeviceLookupByName(VCP, name)); return new Device(this, ptr); } @@ -328,13 +319,9 @@ public class Connect { * description </a> */ public Domain domainCreateLinux(String xmlDesc, int flags) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainCreateLinux(VCP, xmlDesc, flags); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainCreateLinux(VCP, xmlDesc, flags)); + + return new Domain(this, ptr); } /** @@ -347,13 +334,8 @@ public class Connect { * description </a> */ public Domain domainCreateXML(String xmlDesc, int flags) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainCreateXML(VCP, xmlDesc, flags); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainCreateXML(VCP, xmlDesc, flags)); + return new Domain(this, ptr); } /** @@ -366,13 +348,8 @@ public class Connect { * description </a> */ public Domain domainDefineXML(String xmlDesc) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainDefineXML(VCP, xmlDesc); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainDefineXML(VCP, xmlDesc)); + return new Domain(this, ptr); } /** @@ -405,16 +382,15 @@ public class Connect { * the events to monitor * @param cb * the callback function to use. - * @return . The return value from this method is a positive integer - * identifier for the callback. -1 if an error - * @throws LibvirtException + * @return The return value from this method is a positive integer + * identifier for the callback. + * @throws LibvirtException on failure */ public int domainEventRegisterAny(Domain domain, int eventId, Libvirt.VirConnectDomainEventGenericCallback cb) throws LibvirtException { DomainPointer ptr = domain == null ? null : domain.VDP; int returnValue = libvirt.virConnectDomainEventRegisterAny(VCP, ptr, eventId, cb, null, null); - processError(); - return returnValue; + return processError(returnValue); } /** @@ -426,13 +402,8 @@ public class Connect { * @throws LibvirtException */ public Domain domainLookupByID(int id) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainLookupByID(VCP, id); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainLookupByID(VCP, id)); + return new Domain(this, ptr); } /** @@ -444,13 +415,8 @@ public class Connect { * @throws LibvirtException */ public Domain domainLookupByName(String name) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainLookupByName(VCP, name); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainLookupByName(VCP, name)); + return new Domain(this, ptr); } /** @@ -465,13 +431,8 @@ public class Connect { */ public Domain domainLookupByUUID(int[] UUID) throws LibvirtException { byte[] uuidBytes = Connect.createUUIDBytes(UUID); - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainLookupByUUID(VCP, uuidBytes); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainLookupByUUID(VCP, uuidBytes)); + return new Domain(this, ptr); } /** @@ -495,13 +456,8 @@ public class Connect { * @throws LibvirtException */ public Domain domainLookupByUUIDString(String UUID) throws LibvirtException { - Domain returnValue = null; - DomainPointer ptr = libvirt.virDomainLookupByUUIDString(VCP, UUID); - processError(); - if (ptr != null) { - returnValue = new Domain(this, ptr); - } - return returnValue; + DomainPointer ptr = processError(libvirt.virDomainLookupByUUIDString(VCP, UUID)); + return new Domain(this, ptr); } /** @@ -513,9 +469,7 @@ public class Connect { * @throws LibvirtException */ public String domainXMLFromNative(String nativeFormat, String nativeConfig, int flags) throws LibvirtException { - String returnValue = libvirt.virConnectDomainXMLFromNative(VCP, nativeFormat, nativeConfig, 0); - processError(); - return returnValue; + return processError(libvirt.virConnectDomainXMLFromNative(VCP, nativeFormat, nativeConfig, 0)); } /** @@ -528,8 +482,7 @@ public class Connect { */ public String domainXMLToNative(String nativeFormat, String domainXML, int flags) throws LibvirtException { String returnValue = libvirt.virConnectDomainXMLToNative(VCP, nativeFormat, domainXML, 0); - processError(); - return returnValue; + return processError(returnValue); } @Override @@ -559,8 +512,7 @@ public class Connect { */ public String findStoragePoolSources(String type, String srcSpecs, int flags) throws LibvirtException { String returnValue = libvirt.virConnectFindStoragePoolSources(VCP, type, srcSpecs, flags); - processError(); - return returnValue; + return processError(returnValue); } /** @@ -573,8 +525,7 @@ public class Connect { */ public String getCapabilities() throws LibvirtException { String returnValue = libvirt.virConnectGetCapabilities(VCP); - processError(); - return returnValue; + return processError(returnValue); } /** @@ -582,8 +533,10 @@ public class Connect { */ public long getCellsFreeMemory(int startCells, int maxCells) throws LibvirtException { LongByReference returnValue = new LongByReference(); - libvirt.virNodeGetCellsFreeMemory(VCP, returnValue, startCells, maxCells); - processError(); + processError(libvirt.virNodeGetCellsFreeMemory(VCP, + returnValue, + startCells, + maxCells)); return returnValue.getValue(); } @@ -593,7 +546,7 @@ public class Connect { public long getFreeMemory() throws LibvirtException { long returnValue = 0; returnValue = libvirt.virNodeGetFreeMemory(VCP); - processError(); + if (returnValue == 0) processError(); return returnValue; } @@ -606,10 +559,7 @@ public class Connect { * @throws LibvirtException */ public String getHostName() throws LibvirtException { - String returnValue = libvirt.virConnectGetHostname(VCP); - processError(); - return returnValue; - + return processError(libvirt.virConnectGetHostname(VCP)); } /** @@ -624,8 +574,7 @@ public class Connect { public long getHypervisorVersion(String type) throws LibvirtException { LongByReference libVer = new LongByReference(); LongByReference typeVer = new LongByReference(); - libvirt.virGetVersion(libVer, type, typeVer); - processError(); + processError(libvirt.virGetVersion(libVer, type, typeVer)); return libVer.getValue(); } @@ -639,8 +588,7 @@ public class Connect { public long getLibVirVersion() throws LibvirtException { LongByReference libVer = new LongByReference(); LongByReference typeVer = new LongByReference(); - libvirt.virGetVersion(libVer, null, typeVer); - processError(); + processError(libvirt.virGetVersion(libVer, null, typeVer)); return libVer.getValue(); } @@ -654,9 +602,7 @@ public class Connect { * @throws LibvirtException */ public int getMaxVcpus(String type) throws LibvirtException { - int returnValue = libvirt.virConnectGetMaxVcpus(VCP, type); - processError(); - return returnValue; + return processError(libvirt.virConnectGetMaxVcpus(VCP, type)); } /** @@ -666,9 +612,7 @@ public class Connect { * @throws LibvirtException */ public String getType() throws LibvirtException { - String returnValue = libvirt.virConnectGetType(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectGetType(VCP)); } /** @@ -681,9 +625,7 @@ public class Connect { * @throws LibvirtException */ public String getURI() throws LibvirtException { - String returnValue = libvirt.virConnectGetURI(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectGetURI(VCP)); } /** @@ -697,8 +639,7 @@ public class Connect { */ public long getVersion() throws LibvirtException { LongByReference hvVer = new LongByReference(); - libvirt.virConnectGetVersion(VCP, hvVer); - processError(); + processError(libvirt.virConnectGetVersion(VCP, hvVer)); return hvVer.getValue(); } @@ -711,13 +652,8 @@ public class Connect { * @throws LibvirtException */ public Interface interfaceDefineXML(String xmlDesc) throws LibvirtException { - Interface returnValue = null; - InterfacePointer ptr = libvirt.virInterfaceDefineXML(VCP, xmlDesc, 0); - processError(); - if (ptr != null) { - returnValue = new Interface(this, ptr); - } - return returnValue; + InterfacePointer ptr = processError(libvirt.virInterfaceDefineXML(VCP, xmlDesc, 0)); + return new Interface(this, ptr); } /** @@ -726,13 +662,8 @@ public class Connect { * @throws LibvirtException */ public Interface interfaceLookupByMACString(String mac) throws LibvirtException { - Interface returnValue = null; - InterfacePointer ptr = libvirt.virInterfaceLookupByMACString(VCP, mac); - processError(); - if (ptr != null) { - returnValue = new Interface(this, ptr); - } - return returnValue; + InterfacePointer ptr = processError(libvirt.virInterfaceLookupByMACString(VCP, mac)); + return new Interface(this, ptr); } /** @@ -741,13 +672,8 @@ public class Connect { * @throws LibvirtException */ public Interface interfaceLookupByName(String name) throws LibvirtException { - Interface returnValue = null; - InterfacePointer ptr = libvirt.virInterfaceLookupByName(VCP, name); - processError(); - if (ptr != null) { - returnValue = new Interface(this, ptr); - } - return returnValue; + InterfacePointer ptr = processError(libvirt.virInterfaceLookupByName(VCP, name)); + return new Interface(this, ptr); } /** @@ -791,8 +717,7 @@ public class Connect { int maxnames = numOfDefinedDomains(); String[] names = new String[maxnames]; if (maxnames > 0) { - libvirt.virConnectListDefinedDomains(VCP, names, maxnames); - processError(); + processError(libvirt.virConnectListDefinedDomains(VCP, names, maxnames)); } return names; } @@ -808,8 +733,7 @@ public class Connect { int num = numOfDefinedInterfaces(); String[] returnValue = new String[num]; if (num > 0) { - libvirt.virConnectListDefinedInterfaces(VCP, returnValue, num); - processError(); + processError(libvirt.virConnectListDefinedInterfaces(VCP, returnValue, num)); } return returnValue; } @@ -826,8 +750,7 @@ public class Connect { String[] names = new String[maxnames]; if (maxnames > 0) { - libvirt.virConnectListDefinedNetworks(VCP, names, maxnames); - processError(); + processError(libvirt.virConnectListDefinedNetworks(VCP, names, maxnames)); } return names; } @@ -842,8 +765,7 @@ public class Connect { public String[] listDefinedStoragePools() throws LibvirtException { int num = numOfDefinedStoragePools(); String[] returnValue = new String[num]; - libvirt.virConnectListDefinedStoragePools(VCP, returnValue, num); - processError(); + processError(libvirt.virConnectListDefinedStoragePools(VCP, returnValue, num)); return returnValue; } @@ -858,8 +780,7 @@ public class Connect { String[] names = new String[maxDevices]; if (maxDevices > 0) { - libvirt.virNodeListDevices(VCP, capabilityName, names, maxDevices, 0); - processError(); + processError(libvirt.virNodeListDevices(VCP, capabilityName, names, maxDevices, 0)); } return names; } @@ -875,8 +796,7 @@ public class Connect { int[] ids = new int[maxids]; if (maxids > 0) { - libvirt.virConnectListDomains(VCP, ids, maxids); - processError(); + processError(libvirt.virConnectListDomains(VCP, ids, maxids)); } return ids; } @@ -892,8 +812,7 @@ public class Connect { int num = numOfInterfaces(); String[] returnValue = new String[num]; if (num > 0) { - libvirt.virConnectListInterfaces(VCP, returnValue, num); - processError(); + processError(libvirt.virConnectListInterfaces(VCP, returnValue, num)); } return returnValue; } @@ -908,8 +827,7 @@ public class Connect { int maxnames = numOfNetworkFilters(); String[] names = new String[maxnames]; if (maxnames > 0) { - libvirt.virConnectListNWFilters(VCP, names, maxnames); - processError(); + processError(libvirt.virConnectListNWFilters(VCP, names, maxnames)); } return names; } @@ -926,8 +844,7 @@ public class Connect { String[] names = new String[maxnames]; if (maxnames > 0) { - libvirt.virConnectListNetworks(VCP, names, maxnames); - processError(); + processError(libvirt.virConnectListNetworks(VCP, names, maxnames)); } return names; } @@ -941,8 +858,7 @@ public class Connect { public String[] listSecrets() throws LibvirtException { int num = numOfSecrets(); String[] returnValue = new String[num]; - libvirt.virConnectListSecrets(VCP, returnValue, num); - processError(); + processError(libvirt.virConnectListSecrets(VCP, returnValue, num)); return returnValue; } @@ -956,8 +872,7 @@ public class Connect { public String[] listStoragePools() throws LibvirtException { int num = numOfStoragePools(); String[] returnValue = new String[num]; - libvirt.virConnectListStoragePools(VCP, returnValue, num); - processError(); + processError(libvirt.virConnectListStoragePools(VCP, returnValue, num)); return returnValue; } @@ -974,13 +889,8 @@ public class Connect { * description</a> */ public Network networkCreateXML(String xmlDesc) throws LibvirtException { - Network returnValue = null; - NetworkPointer ptr = libvirt.virNetworkCreateXML(VCP, xmlDesc); - processError(); - if (ptr != null) { - returnValue = new Network(this, ptr); - } - return returnValue; + NetworkPointer ptr = processError(libvirt.virNetworkCreateXML(VCP, xmlDesc)); + return new Network(this, ptr); } /** @@ -995,13 +905,8 @@ public class Connect { * description</a> */ public Network networkDefineXML(String xmlDesc) throws LibvirtException { - Network returnValue = null; - NetworkPointer ptr = libvirt.virNetworkDefineXML(VCP, xmlDesc); - processError(); - if (ptr != null) { - returnValue = new Network(this, ptr); - } - return returnValue; + NetworkPointer ptr = processError(libvirt.virNetworkDefineXML(VCP, xmlDesc)); + return new Network(this, ptr); } /** @@ -1016,13 +921,8 @@ public class Connect { * > Libvirt Documentation </a> */ public NetworkFilter networkFilterDefineXML(String xmlDesc) throws LibvirtException { - NetworkFilter returnValue = null; - NetworkFilterPointer ptr = libvirt.virNWFilterDefineXML(VCP, xmlDesc); - processError(); - if (ptr != null) { - returnValue = new NetworkFilter(this, ptr); - } - return returnValue; + NetworkFilterPointer ptr = processError(libvirt.virNWFilterDefineXML(VCP, xmlDesc)); + return new NetworkFilter(this, ptr); } /** @@ -1037,13 +937,8 @@ public class Connect { * > Libvirt Documentation </a> */ public NetworkFilter networkFilterLookupByName(String name) throws LibvirtException { - NetworkFilter returnValue = null; - NetworkFilterPointer ptr = libvirt.virNWFilterLookupByName(VCP, name); - processError(); - if (ptr != null) { - returnValue = new NetworkFilter(this, ptr); - } - return returnValue; + NetworkFilterPointer ptr = processError(libvirt.virNWFilterLookupByName(VCP, name)); + return new NetworkFilter(this, ptr); } /** @@ -1058,13 +953,8 @@ public class Connect { */ public NetworkFilter networkFilterLookupByUUID(int[] UUID) throws LibvirtException { byte[] uuidBytes = Connect.createUUIDBytes(UUID); - NetworkFilter returnValue = null; - NetworkFilterPointer ptr = libvirt.virNWFilterLookupByUUID(VCP, uuidBytes); - processError(); - if (ptr != null) { - returnValue = new NetworkFilter(this, ptr); - } - return returnValue; + NetworkFilterPointer ptr = processError(libvirt.virNWFilterLookupByUUID(VCP, uuidBytes)); + return new NetworkFilter(this, ptr); } /** @@ -1088,13 +978,8 @@ public class Connect { * @throws LibvirtException */ public NetworkFilter networkFilterLookupByUUIDString(String UUID) throws LibvirtException { - NetworkFilter returnValue = null; - NetworkFilterPointer ptr = libvirt.virNWFilterLookupByUUIDString(VCP, UUID); - processError(); - if (ptr != null) { - returnValue = new NetworkFilter(this, ptr); - } - return returnValue; + NetworkFilterPointer ptr = processError(libvirt.virNWFilterLookupByUUIDString(VCP, UUID)); + return new NetworkFilter(this, ptr); } /** @@ -1106,13 +991,8 @@ public class Connect { * @throws LibvirtException */ public Network networkLookupByName(String name) throws LibvirtException { - Network returnValue = null; - NetworkPointer ptr = libvirt.virNetworkLookupByName(VCP, name); - processError(); - if (ptr != null) { - returnValue = new Network(this, ptr); - } - return returnValue; + NetworkPointer ptr = processError(libvirt.virNetworkLookupByName(VCP, name)); + return new Network(this, ptr); } /** @@ -1129,13 +1009,8 @@ public class Connect { @Deprecated public Network networkLookupByUUID(int[] UUID) throws LibvirtException { byte[] uuidBytes = Connect.createUUIDBytes(UUID); - Network returnValue = null; - NetworkPointer ptr = libvirt.virNetworkLookupByUUID(VCP, uuidBytes); - processError(); - if (ptr != null) { - returnValue = new Network(this, ptr); - } - return returnValue; + NetworkPointer ptr = processError(libvirt.virNetworkLookupByUUID(VCP, uuidBytes)); + return new Network(this, ptr); } /** @@ -1159,13 +1034,8 @@ public class Connect { * @throws LibvirtException */ public Network networkLookupByUUIDString(String UUID) throws LibvirtException { - Network returnValue = null; - NetworkPointer ptr = libvirt.virNetworkLookupByUUIDString(VCP, UUID); - processError(); - if (ptr != null) { - returnValue = new Network(this, ptr); - } - return returnValue; + NetworkPointer ptr = processError(libvirt.virNetworkLookupByUUIDString(VCP, UUID)); + return new Network(this, ptr); } /** @@ -1177,8 +1047,7 @@ public class Connect { */ public NodeInfo nodeInfo() throws LibvirtException { virNodeInfo vInfo = new virNodeInfo(); - libvirt.virNodeGetInfo(VCP, vInfo); - processError(); + processError(libvirt.virNodeGetInfo(VCP, vInfo)); return new NodeInfo(vInfo); } @@ -1189,9 +1058,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDefinedDomains() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfDefinedDomains(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfDefinedDomains(VCP)); } /** @@ -1201,9 +1068,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDefinedInterfaces() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfDefinedInterfaces(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfDefinedInterfaces(VCP)); } /** @@ -1213,9 +1078,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDefinedNetworks() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfDefinedNetworks(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfDefinedNetworks(VCP)); } /** @@ -1225,9 +1088,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDefinedStoragePools() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfDefinedStoragePools(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfDefinedStoragePools(VCP)); } /** @@ -1237,9 +1098,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDevices(String capabilityName) throws LibvirtException { - int returnValue = libvirt.virNodeNumOfDevices(VCP, capabilityName, 0); - processError(); - return returnValue; + return processError(libvirt.virNodeNumOfDevices(VCP, capabilityName, 0)); } /** @@ -1249,9 +1108,7 @@ public class Connect { * @throws LibvirtException */ public int numOfDomains() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfDomains(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfDomains(VCP)); } /** @@ -1261,9 +1118,7 @@ public class Connect { * @throws LibvirtException */ public int numOfInterfaces() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfInterfaces(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfInterfaces(VCP)); } /** @@ -1273,9 +1128,7 @@ public class Connect { * @throws LibvirtException */ public int numOfNetworkFilters() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfNWFilters(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfNWFilters(VCP)); } /** @@ -1285,9 +1138,7 @@ public class Connect { * @throws LibvirtException */ public int numOfNetworks() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfNetworks(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfNetworks(VCP)); } /** @@ -1296,9 +1147,7 @@ public class Connect { * @return the number of secrets */ public int numOfSecrets() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfSecrets(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfSecrets(VCP)); } /** @@ -1308,9 +1157,7 @@ public class Connect { * @throws LibvirtException */ public int numOfStoragePools() throws LibvirtException { - int returnValue = libvirt.virConnectNumOfStoragePools(VCP); - processError(); - return returnValue; + return processError(libvirt.virConnectNumOfStoragePools(VCP)); } /** @@ -1323,6 +1170,32 @@ public class Connect { } /** + * Calls {@link #processError()} when the given libvirt return code + * indicates an error. + * + * @param ret libvirt return code, indicating error if negative. + * @return {@code ret} + * @throws LibvirtException + */ + protected final int processError(int ret) throws LibvirtException { + if (ret < 0) processError(); + return ret; + } + + /** + * Calls {@link #processError()} if {@code arg} is null. + * + * @param arg An arbitrary object returned by libvirt. + * @return {@code arg} + * @throws LibvirtException + */ + protected final <T> T processError(T arg) throws LibvirtException { + if (arg == null) processError(); + return arg; + } + + + /** * Restores a domain saved to disk by Domain.save(). * * @param from @@ -1330,8 +1203,7 @@ public class Connect { * @throws LibvirtException */ public void restore(String from) throws LibvirtException { - libvirt.virDomainRestore(VCP, from); - processError(); + processError(libvirt.virDomainRestore(VCP, from)); } /** @@ -1347,13 +1219,8 @@ public class Connect { * @throws LibvirtException */ public Secret secretDefineXML(String xmlDesc) throws LibvirtException { - Secret returnValue = null; - SecretPointer ptr = libvirt.virSecretDefineXML(VCP, xmlDesc, 0); - processError(); - if (ptr != null) { - returnValue = new Secret(this, ptr); - } - return returnValue; + SecretPointer ptr = processError(libvirt.virSecretDefineXML(VCP, xmlDesc, 0)); + return new Secret(this, ptr); } /** @@ -1368,13 +1235,8 @@ public class Connect { */ public Secret secretLookupByUUID(int[] UUID) throws LibvirtException { byte[] uuidBytes = Connect.createUUIDBytes(UUID); - Secret returnValue = null; - SecretPointer ptr = libvirt.virSecretLookupByUUID(VCP, uuidBytes); - processError(); - if (ptr != null) { - returnValue = new Secret(this, ptr); - } - return returnValue; + SecretPointer ptr = processError(libvirt.virSecretLookupByUUID(VCP, uuidBytes)); + return new Secret(this, ptr); } /** @@ -1398,13 +1260,8 @@ public class Connect { * @throws LibvirtException */ public Secret secretLookupByUUIDString(String UUID) throws LibvirtException { - Secret returnValue = null; - SecretPointer ptr = libvirt.virSecretLookupByUUIDString(VCP, UUID); - processError(); - if (ptr != null) { - returnValue = new Secret(this, ptr); - } - return returnValue; + SecretPointer ptr = processError(libvirt.virSecretLookupByUUIDString(VCP, UUID)); + return new Secret(this, ptr); } public void setConnectionErrorCallback(Libvirt.VirErrorCallback callback) throws LibvirtException { @@ -1422,8 +1279,7 @@ public class Connect { * @throws LibvirtException */ public void setDom0Memory(long memory) throws LibvirtException { - libvirt.virDomainSetMemory(null, new NativeLong(memory)); - processError(); + processError(libvirt.virDomainSetMemory(null, new NativeLong(memory))); } /** @@ -1439,8 +1295,7 @@ public class Connect { * @throws LibvirtException */ public StoragePool storagePoolCreateXML(String xmlDesc, int flags) throws LibvirtException { - StoragePoolPointer ptr = libvirt.virStoragePoolCreateXML(VCP, xmlDesc, flags); - processError(); + StoragePoolPointer ptr = processError(libvirt.virStoragePoolCreateXML(VCP, xmlDesc, flags)); return new StoragePool(this, ptr); } @@ -1456,8 +1311,7 @@ public class Connect { * @throws LibvirtException */ public StoragePool storagePoolDefineXML(String xml, int flags) throws LibvirtException { - StoragePoolPointer ptr = libvirt.virStoragePoolDefineXML(VCP, xml, flags); - processError(); + StoragePoolPointer ptr = processError(libvirt.virStoragePoolDefineXML(VCP, xml, flags)); return new StoragePool(this, ptr); } @@ -1470,8 +1324,7 @@ public class Connect { * @throws LibvirtException */ public StoragePool storagePoolLookupByName(String name) throws LibvirtException { - StoragePoolPointer ptr = libvirt.virStoragePoolLookupByName(VCP, name); - processError(); + StoragePoolPointer ptr = processError(libvirt.virStoragePoolLookupByName(VCP, name)); return new StoragePool(this, ptr); } @@ -1487,13 +1340,8 @@ public class Connect { @Deprecated public StoragePool storagePoolLookupByUUID(int[] UUID) throws LibvirtException { byte[] uuidBytes = Connect.createUUIDBytes(UUID); - StoragePool returnValue = null; - StoragePoolPointer ptr = libvirt.virStoragePoolLookupByUUID(VCP, uuidBytes); - processError(); - if (ptr != null) { - returnValue = new StoragePool(this, ptr); - } - return returnValue; + StoragePoolPointer ptr = processError(libvirt.virStoragePoolLookupByUUID(VCP, uuidBytes)); + return new StoragePool(this, ptr); } /** @@ -1517,13 +1365,8 @@ public class Connect { * @throws LibvirtException */ public StoragePool storagePoolLookupByUUIDString(String UUID) throws LibvirtException { - StoragePool returnValue = null; - StoragePoolPointer ptr = libvirt.virStoragePoolLookupByUUIDString(VCP, UUID); - processError(); - if (ptr != null) { - returnValue = new StoragePool(this, ptr); - } - return returnValue; + StoragePoolPointer ptr = processError(libvirt.virStoragePoolLookupByUUIDString(VCP, UUID)); + return new StoragePool(this, ptr); } /** @@ -1534,8 +1377,7 @@ public class Connect { * @return a storage volume */ public StorageVol storageVolLookupByKey(String key) throws LibvirtException { - StorageVolPointer sPtr = libvirt.virStorageVolLookupByKey(VCP, key); - processError(); + StorageVolPointer sPtr = processError(libvirt.virStorageVolLookupByKey(VCP, key)); return new StorageVol(this, sPtr); } @@ -1547,8 +1389,7 @@ public class Connect { * @return a storage volume */ public StorageVol storageVolLookupByPath(String path) throws LibvirtException { - StorageVolPointer sPtr = libvirt.virStorageVolLookupByPath(VCP, path); - processError(); + StorageVolPointer sPtr = processError(libvirt.virStorageVolLookupByPath(VCP, path)); return new StorageVol(this, sPtr); } @@ -1561,8 +1402,7 @@ public class Connect { * @return the new object */ public Stream streamNew(int flags) throws LibvirtException { - StreamPointer sPtr = libvirt.virStreamNew(VCP, flags); - processError(); + StreamPointer sPtr = processError(libvirt.virStreamNew(VCP, flags)); return new Stream(this, sPtr); } -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

The "build" target was split into these individual targets: "build" (default target) only compiles the main files "jar" packages the main files into a jar "buildtests" compiles the test classes The class files are rebuild when any of their dependent source file changed. --- build.xml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/build.xml b/build.xml index 4b73562..970b91a 100644 --- a/build.xml +++ b/build.xml @@ -33,6 +33,7 @@ <target name="init"> <mkdir dir="target/classes" /> <mkdir dir="target/testclasses" /> + <mkdir dir="target/cache" /> <copy file="README.in" tofile="README" overwrite="true" filtering="true"> <filterset filtersfile="build.properties" /> </copy> @@ -42,13 +43,27 @@ <delete dir="target" /> </target> - <target name="build" depends="init" description="builds the code and jar files"> - <javac srcdir="src/main/java" debug="${javac.debug}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" /> - <javac srcdir="src/test/java" debug="${javac.debug}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" /> + <target name="jar" description="build the jar" depends="build"> <jar destfile="${jar.file}" basedir="target/classes" /> </target> - <target name="test" depends="build" description="tests the code"> + <target name="buildtests" description="build test classes" depends="build"> + <depend srcdir="src/test/java" + destdir="target/testclasses" + cache="target/cache" + closure="true" /> + <javac srcdir="src/test/java" debug="${javac.debug}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" /> + </target> + + <target name="build" depends="init" description="builds the code"> + <depend srcdir="src/main/java" + destdir="target/classes" + cache="target/cache" + closure="true" /> + <javac srcdir="src/main/java" debug="${javac.debug}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" /> + </target> + + <target name="test" depends="buildtests" description="tests the code"> <junit printsummary="yes" fork="yes" forkMode="perBatch"> <formatter type="plain" /> <classpath refid="test.classpath" /> @@ -81,7 +96,7 @@ </copy> </target> - <target name="deb" depends="build" description="build a debian Debian package"> + <target name="deb" depends="build,jar" description="build a debian Debian package"> <mkdir dir="${debian.pkgdir}/DEBIAN" /> <copy file="debian/control.in" tofile="${debian.controlfile}" overwrite="true" filtering="true"> <filterset filtersfile="build.properties" /> @@ -103,7 +118,7 @@ <rpm specfile="${spec}" command="-ba" topdir="${rpm.topdir}" /> </target> - <target name="maven" depends="build,docs,src" description="publish the maven repo"> + <target name="maven" depends="build,jar,docs,src" description="publish the maven repo"> <mkdir dir="target/repo" /> <get src="http://repo1.maven.org/maven2/org/apache/maven/maven-ant-tasks/2.1.3/maven-a..." dest="target/maven-ant-tasks-2.1.3.jar" /> <copy file="pom.xml.in" tofile="target/pom.xml" overwrite="true" filtering="true"> -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

The tests have been separated into a test case requiring a libvirt connection and a test case which does not. Every test gets a new Connect instance by using a fixture. This avoids duplicate code and makes tests more consistent. --- build.xml | 9 ++-- src/test/java/org/libvirt/TestJavaBindings.java | 47 +++++++++++---------- src/test/java/org/libvirt/TestLibvirtGlobals.java | 21 +++++++++ 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/build.xml b/build.xml index 0b147b0..4b73562 100644 --- a/build.xml +++ b/build.xml @@ -49,11 +49,14 @@ </target> <target name="test" depends="build" description="tests the code"> - <junit printsummary="yes" fork="yes"> + <junit printsummary="yes" fork="yes" forkMode="perBatch"> <formatter type="plain" /> <classpath refid="test.classpath" /> - <test name="org.libvirt.TestJavaBindings" outfile="target/testResults"> - </test> + <batchtest todir="target"> + <fileset dir="src/test/java"> + <include name="**/Test*.java" /> + </fileset> + </batchtest> </junit> </target> diff --git a/src/test/java/org/libvirt/TestJavaBindings.java b/src/test/java/org/libvirt/TestJavaBindings.java index bac7a82..55ca64b 100644 --- a/src/test/java/org/libvirt/TestJavaBindings.java +++ b/src/test/java/org/libvirt/TestJavaBindings.java @@ -4,28 +4,35 @@ import java.util.UUID; import junit.framework.TestCase; -public class TestJavaBindings extends TestCase { - - int UUIDArray[] = { Integer.decode("0x00"), Integer.decode("0x4b"), Integer.decode("0x96"), Integer.decode("0xe1"), +public final class TestJavaBindings extends TestCase { + final int UUIDArray[] = { Integer.decode("0x00"), Integer.decode("0x4b"), Integer.decode("0x96"), Integer.decode("0xe1"), Integer.decode("0x2d"), Integer.decode("0x78"), Integer.decode("0xc3"), Integer.decode("0x0f"), Integer.decode("0x5a"), Integer.decode("0xa5"), Integer.decode("0xf0"), Integer.decode("0x3c"), Integer.decode("0x87"), Integer.decode("0xd2"), Integer.decode("0x1e"), Integer.decode("0x67") }; - public void testErrorCallback() throws Exception { + private Connect conn; + + protected void setUp() throws LibvirtException { + conn = new Connect("test:///default", false); + } + + protected void tearDown() throws LibvirtException { + conn.close(); + conn = null; + } + + public void testConnectionErrorCallback() throws LibvirtException { DummyErrorCallback cb = new DummyErrorCallback(); - Connect.setErrorCallback(cb); + conn.setConnectionErrorCallback(cb); + try { - Connect conn = new Connect("test:///someUrl", false); - } catch (Exception e) { - // eat it - } - assertTrue("We should have caught an error", cb.error); - Connect conn = new Connect("test:///default", false); - conn.setConnectionErrorCallback(cb) ; + conn.domainDefineXML("fail, miserably"); + } catch (LibvirtException e) {} // ignore + + assertTrue("Error callback was not called", cb.error); } public void testConnection() throws Exception { - Connect conn = new Connect("test:///default", false); assertEquals("conn.getType()", "Test", conn.getType()); assertEquals("conn.getURI()", "test:///default", conn.getURI()); assertEquals("conn.getMaxVcpus(xen)", 32, conn.getMaxVcpus("xen")); @@ -39,7 +46,6 @@ public class TestJavaBindings extends TestCase { } public void testNodeInfo() throws Exception { - Connect conn = new Connect("test:///default", false); NodeInfo nodeInfo = conn.nodeInfo(); assertEquals("nodeInfo.model", "i686", nodeInfo.model); assertEquals("nodeInfo.memory", 3145728, nodeInfo.memory); @@ -56,8 +62,6 @@ public class TestJavaBindings extends TestCase { } public void testNetworkCreate() throws Exception { - Connect conn = new Connect("test:///default", false); - Network network1 = conn.networkCreateXML("<network>" + " <name>createst</name>" + " <uuid>004b96e1-2d78-c30f-5aa5-f03c87d21e68</uuid>" + " <bridge name='createst'/>" + " <forward dev='eth0'/>" + " <ip address='192.168.66.1' netmask='255.255.255.0'>" + " <dhcp>" @@ -103,8 +107,6 @@ public class TestJavaBindings extends TestCase { } public void testDomainCreate() throws Exception { - Connect conn = new Connect("test:///default", false); - Domain dom1 = conn.domainDefineXML("<domain type='test' id='2'>" + " <name>deftest</name>" + " <uuid>004b96e1-2d78-c30f-5aa5-f03c87d21e70</uuid>" + " <memory>8388608</memory>" + " <vcpu>2</vcpu>" + " <os><type arch='i686'>hvm</type></os>" + " <on_reboot>restart</on_reboot>" @@ -129,7 +131,7 @@ public class TestJavaBindings extends TestCase { this.validateDomainData(conn.domainLookupByUUID(UUID.fromString("004b96e1-2d78-c30f-5aa5-f03c87d21e67"))); } - public void validateDomainData(Domain dom) throws Exception { + private void validateDomainData(Domain dom) throws Exception { assertEquals("dom.getName()", "createst", dom.getName()); assertEquals("dom.getMaxMemory()", 8388608, dom.getMaxMemory()); // Not supported by the test driver @@ -162,7 +164,6 @@ public class TestJavaBindings extends TestCase { } public void testInterfaces() throws Exception { - Connect conn = new Connect("test:///default", false); assertEquals("numOfInterfaces:", 1, conn.numOfInterfaces()); assertEquals("numOfInterfaces:", 0, conn.numOfDefinedInterfaces()); assertEquals("listDefinedInterfaces:", "eth1", conn.listInterfaces()[0]); @@ -188,18 +189,18 @@ public class TestJavaBindings extends TestCase { } public void testAccessAfterClose() throws Exception { - Connect conn = new Connect("test:///default", false); conn.close(); assertTrue("conn.isConnected should be false", !conn.isConnected()); + LibvirtException virException = null; try { conn.getHostName(); } catch (LibvirtException e) { - // eat it + virException = e; } + assertNotNull(virException); } public void testStoragePool() throws Exception { - Connect conn = new Connect("test:///default", false); StoragePool pool1 = conn.storagePoolDefineXML("<pool type='dir'>" + " <name>pool1</name>" + " <target>" diff --git a/src/test/java/org/libvirt/TestLibvirtGlobals.java b/src/test/java/org/libvirt/TestLibvirtGlobals.java new file mode 100644 index 0000000..b2b0d9f --- /dev/null +++ b/src/test/java/org/libvirt/TestLibvirtGlobals.java @@ -0,0 +1,21 @@ +package org.libvirt; + +import java.util.UUID; + +import junit.framework.TestCase; + +/** + * libvirt tests not requiring an active connection + */ +public class TestLibvirtGlobals extends TestCase { + public void testErrorCallback() throws Exception { + DummyErrorCallback cb = new DummyErrorCallback(); + Connect.setErrorCallback(cb); + try { + Connect conn = new Connect("test:///someUrl", false); + } catch (LibvirtException e) { + // eat it + } + assertTrue("We should have caught an error", cb.error); + } +} -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

This prevents errors reported by checkstyle, see http://checkstyle.sourceforge.net/config_modifier.html#RedundantModifier JSL 9.4: It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface. --- src/main/java/org/libvirt/jna/Libvirt.java | 486 ++++++++++++++-------------- 1 file changed, 243 insertions(+), 243 deletions(-) diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index e68d9ed..02457b7 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -64,40 +64,40 @@ public interface Libvirt extends Library { * Callback interface for authorization */ interface VirConnectAuthCallback extends Callback { - public int authCallback(virConnectCredential cred, int ncred, Pointer cbdata); + int authCallback(virConnectCredential cred, int ncred, Pointer cbdata); } /** * Error callback */ interface VirErrorCallback extends Callback { - public void errorCallback(Pointer userData, virError error); + void errorCallback(Pointer userData, virError error); } /** * Stream callbacks */ interface VirStreamSinkFunc extends Callback { - public int sinkCallback(StreamPointer virStreamPtr, String data, NativeLong nbytes, Pointer opaque) ; + int sinkCallback(StreamPointer virStreamPtr, String data, NativeLong nbytes, Pointer opaque) ; } interface VirStreamSourceFunc extends Callback { - public int sourceCallback(StreamPointer virStreamPtr, String data, NativeLong nbytes, Pointer opaque) ; + int sourceCallback(StreamPointer virStreamPtr, String data, NativeLong nbytes, Pointer opaque) ; } interface VirStreamEventCallback extends Callback { - public void eventCallback(StreamPointer virStreamPointer, int events, Pointer opaque) ; + void eventCallback(StreamPointer virStreamPointer, int events, Pointer opaque) ; } /** * Generic Callbacks */ interface VirFreeCallback extends Callback { - public void freeCallback(Pointer opaque) ; + void freeCallback(Pointer opaque) ; } interface VirConnectDomainEventGenericCallback extends Callback { - public void eventCallback(ConnectionPointer virConnectPtr, DomainPointer virDomainPointer, Pointer opaque) ; + void eventCallback(ConnectionPointer virConnectPtr, DomainPointer virDomainPointer, Pointer opaque) ; } Libvirt INSTANCE = (Libvirt) Native.loadLibrary("virt", Libvirt.class); @@ -108,274 +108,274 @@ public interface Libvirt extends Library { public static int VIR_DOMAIN_SCHED_FIELD_LENGTH = 80; // Connection Functions - public String virConnectBaselineCPU(ConnectionPointer virConnectPtr, String[] xmlCPUs, int ncpus, int flags); - public int virConnCopyLastError(ConnectionPointer virConnectPtr, virError to); - public int virConnectClose(ConnectionPointer virConnectPtr); - public int virConnectCompareCPU(ConnectionPointer virConnectPtr, String xmlDesc, int flags); - public int virConnectDomainEventRegisterAny(ConnectionPointer virConnectPtr, DomainPointer virDomainPtr, int eventID, Libvirt.VirConnectDomainEventGenericCallback cb, Pointer opaque, Libvirt.VirFreeCallback freecb); - public int virConnectDomainEventDeregisterAny(ConnectionPointer virConnectPtr, int callbackID) ; - public void virConnSetErrorFunc(ConnectionPointer virConnectPtr, Pointer userData, VirErrorCallback callback); - public int virConnectIsEncrypted(ConnectionPointer virConnectPtr) ; - public int virConnectIsSecure(ConnectionPointer virConnectPtr) ; - public String virConnectFindStoragePoolSources(ConnectionPointer virConnectPtr, String type, String srcSpec, int flags); - public String virConnectGetCapabilities(ConnectionPointer virConnectPtr); - public String virConnectGetHostname(ConnectionPointer virConnectPtr); - public int virConnectGetLibVersion(ConnectionPointer virConnectPtr, LongByReference libVer); - public int virConnectGetMaxVcpus(ConnectionPointer virConnectPtr, String type); - public String virConnectGetType(ConnectionPointer virConnectPtr); - public String virConnectGetURI(ConnectionPointer virConnectPtr); - public int virConnectGetVersion(ConnectionPointer virConnectPtr, LongByReference hvVer); - public int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, String[] name, int maxnames); - public int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); - public int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); - public int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); - public int virConnectListDomains(ConnectionPointer virConnectPtr, int[] ids, int maxnames); - public int virConnectListInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); - public int virConnectListNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); - public int virConnectListNWFilters(ConnectionPointer virConnectPtr, String[] name, int maxnames); - public int virConnectListSecrets(ConnectionPointer virConnectPtr, String[] uids, int maxUids); - public int virConnectListStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); - public int virConnectNumOfDefinedDomains(ConnectionPointer virConnectPtr); - public int virConnectNumOfDefinedNetworks(ConnectionPointer virConnectPtr); - public int virConnectNumOfDefinedInterfaces(ConnectionPointer virConnectPtr); - public int virConnectNumOfDefinedStoragePools(ConnectionPointer virConnectPtr); - public int virConnectNumOfDomains(ConnectionPointer virConnectPtr); - public int virConnectNumOfInterfaces(ConnectionPointer virConnectPtr); - public int virConnectNumOfNetworks(ConnectionPointer virConnectPtr); - public int virConnectNumOfNWFilters(ConnectionPointer virConnectPtr); - public int virConnectNumOfSecrets(ConnectionPointer virConnectPtr); - public int virConnectNumOfStoragePools(ConnectionPointer virConnectPtr); - public ConnectionPointer virConnectOpen(String name); - public ConnectionPointer virConnectOpenAuth(String name, virConnectAuth auth, int flags); - public ConnectionPointer virConnectOpenReadOnly(String name); - public virError virConnGetLastError(ConnectionPointer virConnectPtr); - public int virConnResetLastError(ConnectionPointer virConnectPtr); - public String virConnectDomainXMLFromNative(ConnectionPointer virConnectPtr, String nativeFormat, + String virConnectBaselineCPU(ConnectionPointer virConnectPtr, String[] xmlCPUs, int ncpus, int flags); + int virConnCopyLastError(ConnectionPointer virConnectPtr, virError to); + int virConnectClose(ConnectionPointer virConnectPtr); + int virConnectCompareCPU(ConnectionPointer virConnectPtr, String xmlDesc, int flags); + int virConnectDomainEventRegisterAny(ConnectionPointer virConnectPtr, DomainPointer virDomainPtr, int eventID, Libvirt.VirConnectDomainEventGenericCallback cb, Pointer opaque, Libvirt.VirFreeCallback freecb); + int virConnectDomainEventDeregisterAny(ConnectionPointer virConnectPtr, int callbackID) ; + void virConnSetErrorFunc(ConnectionPointer virConnectPtr, Pointer userData, VirErrorCallback callback); + int virConnectIsEncrypted(ConnectionPointer virConnectPtr) ; + int virConnectIsSecure(ConnectionPointer virConnectPtr) ; + String virConnectFindStoragePoolSources(ConnectionPointer virConnectPtr, String type, String srcSpec, int flags); + String virConnectGetCapabilities(ConnectionPointer virConnectPtr); + String virConnectGetHostname(ConnectionPointer virConnectPtr); + int virConnectGetLibVersion(ConnectionPointer virConnectPtr, LongByReference libVer); + int virConnectGetMaxVcpus(ConnectionPointer virConnectPtr, String type); + String virConnectGetType(ConnectionPointer virConnectPtr); + String virConnectGetURI(ConnectionPointer virConnectPtr); + int virConnectGetVersion(ConnectionPointer virConnectPtr, LongByReference hvVer); + int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, String[] name, int maxnames); + int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); + int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); + int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); + int virConnectListDomains(ConnectionPointer virConnectPtr, int[] ids, int maxnames); + int virConnectListInterfaces(ConnectionPointer virConnectPtr, String[] name, int maxNames); + int virConnectListNetworks(ConnectionPointer virConnectPtr, String[] name, int maxnames); + int virConnectListNWFilters(ConnectionPointer virConnectPtr, String[] name, int maxnames); + int virConnectListSecrets(ConnectionPointer virConnectPtr, String[] uids, int maxUids); + int virConnectListStoragePools(ConnectionPointer virConnectPtr, String[] names, int maxnames); + int virConnectNumOfDefinedDomains(ConnectionPointer virConnectPtr); + int virConnectNumOfDefinedNetworks(ConnectionPointer virConnectPtr); + int virConnectNumOfDefinedInterfaces(ConnectionPointer virConnectPtr); + int virConnectNumOfDefinedStoragePools(ConnectionPointer virConnectPtr); + int virConnectNumOfDomains(ConnectionPointer virConnectPtr); + int virConnectNumOfInterfaces(ConnectionPointer virConnectPtr); + int virConnectNumOfNetworks(ConnectionPointer virConnectPtr); + int virConnectNumOfNWFilters(ConnectionPointer virConnectPtr); + int virConnectNumOfSecrets(ConnectionPointer virConnectPtr); + int virConnectNumOfStoragePools(ConnectionPointer virConnectPtr); + ConnectionPointer virConnectOpen(String name); + ConnectionPointer virConnectOpenAuth(String name, virConnectAuth auth, int flags); + ConnectionPointer virConnectOpenReadOnly(String name); + virError virConnGetLastError(ConnectionPointer virConnectPtr); + int virConnResetLastError(ConnectionPointer virConnectPtr); + String virConnectDomainXMLFromNative(ConnectionPointer virConnectPtr, String nativeFormat, String nativeConfig, int flags); - public String virConnectDomainXMLToNative(ConnectionPointer virConnectPtr, String nativeFormat, String domainXML, + String virConnectDomainXMLToNative(ConnectionPointer virConnectPtr, String nativeFormat, String domainXML, int flags); // Global functions - public int virGetVersion(LongByReference libVer, String type, LongByReference typeVer); - public int virInitialize(); - public int virCopyLastError(virError error); - public virError virGetLastError(); - public void virResetLastError(); - public void virSetErrorFunc(Pointer userData, VirErrorCallback callback); + int virGetVersion(LongByReference libVer, String type, LongByReference typeVer); + int virInitialize(); + int virCopyLastError(virError error); + virError virGetLastError(); + void virResetLastError(); + void virSetErrorFunc(Pointer userData, VirErrorCallback callback); // Domain functions - public int virDomainAbortJob(DomainPointer virDomainPtr); - public int virDomainAttachDevice(DomainPointer virDomainPtr, String deviceXML); - public int virDomainAttachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); - public int virDomainBlockStats(DomainPointer virDomainPtr, String path, virDomainBlockStats stats, int size); - public int virDomainCoreDump(DomainPointer virDomainPtr, String to, int flags); - public int virDomainCreate(DomainPointer virDomainPtr); - public int virDomainCreateWithFlags(DomainPointer virDomainPtr, int flags); - public DomainPointer virDomainCreateLinux(ConnectionPointer virConnectPtr, String xmlDesc, int flags); - public DomainPointer virDomainCreateXML(ConnectionPointer virConnectPtr, String xmlDesc, int flags); - public DomainPointer virDomainDefineXML(ConnectionPointer virConnectPtr, String xmlDesc); - public int virDomainDestroy(DomainPointer virDomainPtr); - public int virDomainDetachDevice(DomainPointer virDomainPtr, String deviceXML); - public int virDomainDetachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); - public int virDomainFree(DomainPointer virDomainPtr); - public int virDomainGetAutostart(DomainPointer virDomainPtr, IntByReference value); - public ConnectionPointer virDomainGetConnect(DomainPointer virDomainPtr); - public int virDomainGetBlockInfo(DomainPointer virDomainPtr, String path, virDomainBlockInfo info, int flags); - public int virDomainGetID(DomainPointer virDomainPtr); - public int virDomainGetInfo(DomainPointer virDomainPtr, virDomainInfo vInfo); - public int virDomainGetJobInfo(DomainPointer virDomainPtr, virDomainJobInfo vInfo); - public NativeLong virDomainGetMaxMemory(DomainPointer virDomainPtr); - public int virDomainGetMaxVcpus(DomainPointer virDomainPtr); - public String virDomainGetName(DomainPointer virDomainPtr); - public String virDomainGetOSType(DomainPointer virDomainPtr); - public int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, + int virDomainAbortJob(DomainPointer virDomainPtr); + int virDomainAttachDevice(DomainPointer virDomainPtr, String deviceXML); + int virDomainAttachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); + int virDomainBlockStats(DomainPointer virDomainPtr, String path, virDomainBlockStats stats, int size); + int virDomainCoreDump(DomainPointer virDomainPtr, String to, int flags); + int virDomainCreate(DomainPointer virDomainPtr); + int virDomainCreateWithFlags(DomainPointer virDomainPtr, int flags); + DomainPointer virDomainCreateLinux(ConnectionPointer virConnectPtr, String xmlDesc, int flags); + DomainPointer virDomainCreateXML(ConnectionPointer virConnectPtr, String xmlDesc, int flags); + DomainPointer virDomainDefineXML(ConnectionPointer virConnectPtr, String xmlDesc); + int virDomainDestroy(DomainPointer virDomainPtr); + int virDomainDetachDevice(DomainPointer virDomainPtr, String deviceXML); + int virDomainDetachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); + int virDomainFree(DomainPointer virDomainPtr); + int virDomainGetAutostart(DomainPointer virDomainPtr, IntByReference value); + ConnectionPointer virDomainGetConnect(DomainPointer virDomainPtr); + int virDomainGetBlockInfo(DomainPointer virDomainPtr, String path, virDomainBlockInfo info, int flags); + int virDomainGetID(DomainPointer virDomainPtr); + int virDomainGetInfo(DomainPointer virDomainPtr, virDomainInfo vInfo); + int virDomainGetJobInfo(DomainPointer virDomainPtr, virDomainJobInfo vInfo); + NativeLong virDomainGetMaxMemory(DomainPointer virDomainPtr); + int virDomainGetMaxVcpus(DomainPointer virDomainPtr); + String virDomainGetName(DomainPointer virDomainPtr); + String virDomainGetOSType(DomainPointer virDomainPtr); + int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, IntByReference nparams); Pointer virDomainGetSchedulerType(DomainPointer virDomainPtr, IntByReference nparams); - public int virDomainGetUUID(DomainPointer virDomainPtr, byte[] uuidString); - public int virDomainGetUUIDString(DomainPointer virDomainPtr, byte[] uuidString); - public int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, int maxInfo, byte[] cpumaps, int maplen); - public String virDomainGetXMLDesc(DomainPointer virDomainPtr, int flags); - public int virDomainHasCurrentSnapshot(DomainPointer virDomainPtr, int flags); - public int virDomainHasManagedSaveImage(DomainPointer virDomainPtr, int flags); - public int virDomainInterfaceStats(DomainPointer virDomainPtr, String path, virDomainInterfaceStats stats, int size); - public int virDomainIsActive(DomainPointer virDomainPtr); - public int virDomainIsPersistent(DomainPointer virDomainPtr); - public DomainPointer virDomainLookupByID(ConnectionPointer virConnectPtr, int id); - public DomainPointer virDomainLookupByName(ConnectionPointer virConnectPtr, String name); - public DomainPointer virDomainLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); - public DomainPointer virDomainLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); - public int virDomainManagedSave(DomainPointer virDomainPtr, int flags); - public int virDomainManagedSaveRemove(DomainPointer virDomainPtr, int flags); - public DomainPointer virDomainMigrate(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, + int virDomainGetUUID(DomainPointer virDomainPtr, byte[] uuidString); + int virDomainGetUUIDString(DomainPointer virDomainPtr, byte[] uuidString); + int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, int maxInfo, byte[] cpumaps, int maplen); + String virDomainGetXMLDesc(DomainPointer virDomainPtr, int flags); + int virDomainHasCurrentSnapshot(DomainPointer virDomainPtr, int flags); + int virDomainHasManagedSaveImage(DomainPointer virDomainPtr, int flags); + int virDomainInterfaceStats(DomainPointer virDomainPtr, String path, virDomainInterfaceStats stats, int size); + int virDomainIsActive(DomainPointer virDomainPtr); + int virDomainIsPersistent(DomainPointer virDomainPtr); + DomainPointer virDomainLookupByID(ConnectionPointer virConnectPtr, int id); + DomainPointer virDomainLookupByName(ConnectionPointer virConnectPtr, String name); + DomainPointer virDomainLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); + DomainPointer virDomainLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); + int virDomainManagedSave(DomainPointer virDomainPtr, int flags); + int virDomainManagedSaveRemove(DomainPointer virDomainPtr, int flags); + DomainPointer virDomainMigrate(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, NativeLong flags, String dname, String uri, NativeLong bandwidth); - public int virDomainMigrateSetMaxDowntime(DomainPointer virDomainPtr, long downtime, int flags); - public int virDomainMigrateToURI(DomainPointer virDomainPtr, String duri, + int virDomainMigrateSetMaxDowntime(DomainPointer virDomainPtr, long downtime, int flags); + int virDomainMigrateToURI(DomainPointer virDomainPtr, String duri, NativeLong flags, String dname, NativeLong bandwidth); - public int virDomainMemoryStats(DomainPointer virDomainPtr, virDomainMemoryStats[] stats, int nr_stats, int flags); - public int virDomainPinVcpu(DomainPointer virDomainPtr, int vcpu, byte[] cpumap, int maplen); - public int virDomainReboot(DomainPointer virDomainPtr, int flags); - public int virDomainRestore(ConnectionPointer virConnectPtr, String from); - public int virDomainRevertToSnapshot(DomainSnapshotPointer virDomainSnapshotPtr, int flags); - public int virDomainResume(DomainPointer virDomainPtr); - public int virDomainSave(DomainPointer virDomainPtr, String to); - public int virDomainSetAutostart(DomainPointer virDomainPtr, int autoStart); - public int virDomainSetMaxMemory(DomainPointer virDomainPtr, NativeLong maxMemory); - public int virDomainSetMemory(DomainPointer virDomainPtr, NativeLong maxMemory); - public int virDomainSetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, int nparams); - public int virDomainSetVcpus(DomainPointer virDomainPtr, int nvcpus); - public int virDomainShutdown(DomainPointer virDomainPtr); - public int virDomainSuspend(DomainPointer virDomainPtr); - public int virDomainUpdateDeviceFlags(DomainPointer virDomainPtr, String xml, int flags); - public int virDomainUndefine(DomainPointer virDomainPtr); + int virDomainMemoryStats(DomainPointer virDomainPtr, virDomainMemoryStats[] stats, int nr_stats, int flags); + int virDomainPinVcpu(DomainPointer virDomainPtr, int vcpu, byte[] cpumap, int maplen); + int virDomainReboot(DomainPointer virDomainPtr, int flags); + int virDomainRestore(ConnectionPointer virConnectPtr, String from); + int virDomainRevertToSnapshot(DomainSnapshotPointer virDomainSnapshotPtr, int flags); + int virDomainResume(DomainPointer virDomainPtr); + int virDomainSave(DomainPointer virDomainPtr, String to); + int virDomainSetAutostart(DomainPointer virDomainPtr, int autoStart); + int virDomainSetMaxMemory(DomainPointer virDomainPtr, NativeLong maxMemory); + int virDomainSetMemory(DomainPointer virDomainPtr, NativeLong maxMemory); + int virDomainSetSchedulerParameters(DomainPointer virDomainPtr, virSchedParameter[] params, int nparams); + int virDomainSetVcpus(DomainPointer virDomainPtr, int nvcpus); + int virDomainShutdown(DomainPointer virDomainPtr); + int virDomainSuspend(DomainPointer virDomainPtr); + int virDomainUpdateDeviceFlags(DomainPointer virDomainPtr, String xml, int flags); + int virDomainUndefine(DomainPointer virDomainPtr); // Network functions - public ConnectionPointer virNetworkGetConnect(NetworkPointer virnetworkPtr); - public int virNetworkCreate(NetworkPointer virConnectPtr); - public NetworkPointer virNetworkCreateXML(ConnectionPointer virConnectPtr, String xmlDesc); - public NetworkPointer virNetworkDefineXML(ConnectionPointer virConnectPtr, String xmlDesc); - public int virNetworkDestroy(NetworkPointer virConnectPtr); - public int virNetworkFree(NetworkPointer virConnectPtr); - public int virNetworkGetAutostart(NetworkPointer virNetworkPtr, IntByReference value); - public String virNetworkGetBridgeName(NetworkPointer virNetworkPtr); - public String virNetworkGetName(NetworkPointer virNetworkPtr); - public int virNetworkGetUUID(NetworkPointer virNetworkPtr, byte[] uuidString); - public int virNetworkGetUUIDString(NetworkPointer virNetworkPtr, byte[] uuidString); - public String virNetworkGetXMLDesc(NetworkPointer virNetworkPtr, int flags); - public int virNetworkIsActive(NetworkPointer virNetworkPtr); - public int virNetworkIsPersistent(NetworkPointer virNetworkPtr); - public NetworkPointer virNetworkLookupByName(ConnectionPointer virConnectPtr, String name); - public NetworkPointer virNetworkLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); - public NetworkPointer virNetworkLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); - public int virNetworkSetAutostart(NetworkPointer virConnectPtr, int autoStart); - public int virNetworkUndefine(NetworkPointer virConnectPtr); + ConnectionPointer virNetworkGetConnect(NetworkPointer virnetworkPtr); + int virNetworkCreate(NetworkPointer virConnectPtr); + NetworkPointer virNetworkCreateXML(ConnectionPointer virConnectPtr, String xmlDesc); + NetworkPointer virNetworkDefineXML(ConnectionPointer virConnectPtr, String xmlDesc); + int virNetworkDestroy(NetworkPointer virConnectPtr); + int virNetworkFree(NetworkPointer virConnectPtr); + int virNetworkGetAutostart(NetworkPointer virNetworkPtr, IntByReference value); + String virNetworkGetBridgeName(NetworkPointer virNetworkPtr); + String virNetworkGetName(NetworkPointer virNetworkPtr); + int virNetworkGetUUID(NetworkPointer virNetworkPtr, byte[] uuidString); + int virNetworkGetUUIDString(NetworkPointer virNetworkPtr, byte[] uuidString); + String virNetworkGetXMLDesc(NetworkPointer virNetworkPtr, int flags); + int virNetworkIsActive(NetworkPointer virNetworkPtr); + int virNetworkIsPersistent(NetworkPointer virNetworkPtr); + NetworkPointer virNetworkLookupByName(ConnectionPointer virConnectPtr, String name); + NetworkPointer virNetworkLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); + NetworkPointer virNetworkLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); + int virNetworkSetAutostart(NetworkPointer virConnectPtr, int autoStart); + int virNetworkUndefine(NetworkPointer virConnectPtr); // Node functions - public int virNodeGetInfo(ConnectionPointer virConnectPtr, virNodeInfo virNodeInfo); - public int virNodeGetCellsFreeMemory(ConnectionPointer virConnectPtr, LongByReference freeMems, int startCell, + int virNodeGetInfo(ConnectionPointer virConnectPtr, virNodeInfo virNodeInfo); + int virNodeGetCellsFreeMemory(ConnectionPointer virConnectPtr, LongByReference freeMems, int startCell, int maxCells); - public long virNodeGetFreeMemory(ConnectionPointer virConnectPtr); + long virNodeGetFreeMemory(ConnectionPointer virConnectPtr); // Node/Device functions - public int virNodeNumOfDevices(ConnectionPointer virConnectPtr, String capabilityName, int flags); - public int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, String[] names, int maxnames, + int virNodeNumOfDevices(ConnectionPointer virConnectPtr, String capabilityName, int flags); + int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, String[] names, int maxnames, int flags); - public DevicePointer virNodeDeviceLookupByName(ConnectionPointer virConnectPtr, String name); - public String virNodeDeviceGetName(DevicePointer virDevicePointer); - public String virNodeDeviceGetParent(DevicePointer virDevicePointer); - public int virNodeDeviceNumOfCaps(DevicePointer virDevicePointer); - public int virNodeDeviceListCaps(DevicePointer virDevicePointer, String[] names, int maxNames); - public String virNodeDeviceGetXMLDesc(DevicePointer virDevicePointer); - public int virNodeDeviceFree(DevicePointer virDevicePointer); - public int virNodeDeviceDettach(DevicePointer virDevicePointer); - public int virNodeDeviceReAttach(DevicePointer virDevicePointer); - public int virNodeDeviceReset(DevicePointer virDevicePointer); - public DevicePointer virNodeDeviceCreateXML(ConnectionPointer virConnectPtr, String xml, int flags); - public int virNodeDeviceDestroy(DevicePointer virDevicePointer); + DevicePointer virNodeDeviceLookupByName(ConnectionPointer virConnectPtr, String name); + String virNodeDeviceGetName(DevicePointer virDevicePointer); + String virNodeDeviceGetParent(DevicePointer virDevicePointer); + int virNodeDeviceNumOfCaps(DevicePointer virDevicePointer); + int virNodeDeviceListCaps(DevicePointer virDevicePointer, String[] names, int maxNames); + String virNodeDeviceGetXMLDesc(DevicePointer virDevicePointer); + int virNodeDeviceFree(DevicePointer virDevicePointer); + int virNodeDeviceDettach(DevicePointer virDevicePointer); + int virNodeDeviceReAttach(DevicePointer virDevicePointer); + int virNodeDeviceReset(DevicePointer virDevicePointer); + DevicePointer virNodeDeviceCreateXML(ConnectionPointer virConnectPtr, String xml, int flags); + int virNodeDeviceDestroy(DevicePointer virDevicePointer); // Storage Pool - public int virStoragePoolBuild(StoragePoolPointer storagePoolPtr, int flags); - public int virStoragePoolCreate(StoragePoolPointer storagePoolPtr, int flags); - public StoragePoolPointer virStoragePoolCreateXML(ConnectionPointer virConnectPtr, String xml, int flags); - public StoragePoolPointer virStoragePoolDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); - public int virStoragePoolDelete(StoragePoolPointer storagePoolPtr, int flags); - public int virStoragePoolDestroy(StoragePoolPointer storagePoolPtr); - public int virStoragePoolFree(StoragePoolPointer storagePoolPtr); - public int virStoragePoolGetAutostart(StoragePoolPointer storagePoolPtr, IntByReference value); - public int virStoragePoolGetInfo(StoragePoolPointer storagePoolPtr, virStoragePoolInfo info); - public String virStoragePoolGetName(StoragePoolPointer storagePoolPtr); - public int virStoragePoolGetUUID(StoragePoolPointer storagePoolPtr, byte[] uuidString); - public int virStoragePoolGetUUIDString(StoragePoolPointer storagePoolPtr, byte[] uuidString); - public String virStoragePoolGetXMLDesc(StoragePoolPointer storagePoolPtr, int flags); - public int virStoragePoolListVolumes(StoragePoolPointer storagePoolPtr, String[] names, int maxnames); - public int virStoragePoolIsActive(StoragePoolPointer storagePoolPtr); - public int virStoragePoolIsPersistent(StoragePoolPointer storagePoolPtr); - public StoragePoolPointer virStoragePoolLookupByName(ConnectionPointer virConnectPtr, String name); - public StoragePoolPointer virStoragePoolLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); - public StoragePoolPointer virStoragePoolLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); - public StoragePoolPointer virStoragePoolLookupByVolume(StorageVolPointer storageVolPtr); - public int virStoragePoolNumOfVolumes(StoragePoolPointer storagePoolPtr); - public int virStoragePoolRefresh(StoragePoolPointer storagePoolPtr, int flags); - public int virStoragePoolSetAutostart(StoragePoolPointer storagePoolPtr, int autostart); - public int virStoragePoolUndefine(StoragePoolPointer storagePoolPtr); + int virStoragePoolBuild(StoragePoolPointer storagePoolPtr, int flags); + int virStoragePoolCreate(StoragePoolPointer storagePoolPtr, int flags); + StoragePoolPointer virStoragePoolCreateXML(ConnectionPointer virConnectPtr, String xml, int flags); + StoragePoolPointer virStoragePoolDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); + int virStoragePoolDelete(StoragePoolPointer storagePoolPtr, int flags); + int virStoragePoolDestroy(StoragePoolPointer storagePoolPtr); + int virStoragePoolFree(StoragePoolPointer storagePoolPtr); + int virStoragePoolGetAutostart(StoragePoolPointer storagePoolPtr, IntByReference value); + int virStoragePoolGetInfo(StoragePoolPointer storagePoolPtr, virStoragePoolInfo info); + String virStoragePoolGetName(StoragePoolPointer storagePoolPtr); + int virStoragePoolGetUUID(StoragePoolPointer storagePoolPtr, byte[] uuidString); + int virStoragePoolGetUUIDString(StoragePoolPointer storagePoolPtr, byte[] uuidString); + String virStoragePoolGetXMLDesc(StoragePoolPointer storagePoolPtr, int flags); + int virStoragePoolListVolumes(StoragePoolPointer storagePoolPtr, String[] names, int maxnames); + int virStoragePoolIsActive(StoragePoolPointer storagePoolPtr); + int virStoragePoolIsPersistent(StoragePoolPointer storagePoolPtr); + StoragePoolPointer virStoragePoolLookupByName(ConnectionPointer virConnectPtr, String name); + StoragePoolPointer virStoragePoolLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); + StoragePoolPointer virStoragePoolLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); + StoragePoolPointer virStoragePoolLookupByVolume(StorageVolPointer storageVolPtr); + int virStoragePoolNumOfVolumes(StoragePoolPointer storagePoolPtr); + int virStoragePoolRefresh(StoragePoolPointer storagePoolPtr, int flags); + int virStoragePoolSetAutostart(StoragePoolPointer storagePoolPtr, int autostart); + int virStoragePoolUndefine(StoragePoolPointer storagePoolPtr); // Storage Vol - public StorageVolPointer virStorageVolCreateXML(StoragePoolPointer storagePoolPtr, String xml, int flags); - public StorageVolPointer virStorageVolCreateXMLFrom(StoragePoolPointer storagePoolPtr, String xml, + StorageVolPointer virStorageVolCreateXML(StoragePoolPointer storagePoolPtr, String xml, int flags); + StorageVolPointer virStorageVolCreateXMLFrom(StoragePoolPointer storagePoolPtr, String xml, StorageVolPointer cloneVolume, int flags); - public int virStorageVolDelete(StorageVolPointer storageVolPtr, int flags); - public int virStorageVolFree(StorageVolPointer storageVolPtr); - public int virStorageVolGetInfo(StorageVolPointer storageVolPtr, virStorageVolInfo info); - public String virStorageVolGetKey(StorageVolPointer storageVolPtr); - public String virStorageVolGetName(StorageVolPointer storageVolPtr); - public String virStorageVolGetPath(StorageVolPointer storageVolPtr); - public String virStorageVolGetXMLDesc(StorageVolPointer storageVolPtr, int flags); - public StorageVolPointer virStorageVolLookupByKey(ConnectionPointer virConnectPtr, String name); - public StorageVolPointer virStorageVolLookupByName(StoragePoolPointer storagePoolPtr, String name); - public StorageVolPointer virStorageVolLookupByPath(ConnectionPointer virConnectPtr, String path); - public int virStorageVolWipe(StorageVolPointer storageVolPtr, int flags); + int virStorageVolDelete(StorageVolPointer storageVolPtr, int flags); + int virStorageVolFree(StorageVolPointer storageVolPtr); + int virStorageVolGetInfo(StorageVolPointer storageVolPtr, virStorageVolInfo info); + String virStorageVolGetKey(StorageVolPointer storageVolPtr); + String virStorageVolGetName(StorageVolPointer storageVolPtr); + String virStorageVolGetPath(StorageVolPointer storageVolPtr); + String virStorageVolGetXMLDesc(StorageVolPointer storageVolPtr, int flags); + StorageVolPointer virStorageVolLookupByKey(ConnectionPointer virConnectPtr, String name); + StorageVolPointer virStorageVolLookupByName(StoragePoolPointer storagePoolPtr, String name); + StorageVolPointer virStorageVolLookupByPath(ConnectionPointer virConnectPtr, String path); + int virStorageVolWipe(StorageVolPointer storageVolPtr, int flags); // Interface Methods - public int virInterfaceCreate(InterfacePointer virDevicePointer); - public InterfacePointer virInterfaceDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); - public int virInterfaceDestroy(InterfacePointer virDevicePointer); - public int virInterfaceFree(InterfacePointer virDevicePointer); - public String virInterfaceGetName(InterfacePointer virInterfacePtr); - public String virInterfaceGetMACString(InterfacePointer virInterfacePtr); - public String virInterfaceGetXMLDesc(InterfacePointer virInterfacePtr, int flags); - public int virInterfaceIsActive(InterfacePointer virDevicePointer); - public InterfacePointer virInterfaceLookupByMACString(ConnectionPointer virConnectPtr, String mac); - public InterfacePointer virInterfaceLookupByName(ConnectionPointer virConnectPtr, String name); - public int virInterfaceUndefine(InterfacePointer virDevicePointer); + int virInterfaceCreate(InterfacePointer virDevicePointer); + InterfacePointer virInterfaceDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); + int virInterfaceDestroy(InterfacePointer virDevicePointer); + int virInterfaceFree(InterfacePointer virDevicePointer); + String virInterfaceGetName(InterfacePointer virInterfacePtr); + String virInterfaceGetMACString(InterfacePointer virInterfacePtr); + String virInterfaceGetXMLDesc(InterfacePointer virInterfacePtr, int flags); + int virInterfaceIsActive(InterfacePointer virDevicePointer); + InterfacePointer virInterfaceLookupByMACString(ConnectionPointer virConnectPtr, String mac); + InterfacePointer virInterfaceLookupByName(ConnectionPointer virConnectPtr, String name); + int virInterfaceUndefine(InterfacePointer virDevicePointer); // Secret Methods - public ConnectionPointer virSecretGetConnect(SecretPointer virSecretPtr); - public int virSecretFree(SecretPointer virSecretPtr); - public SecretPointer virSecretDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); - public int virSecretGetUUID(SecretPointer virSecretPtr, byte[] uuidString); - public int virSecretGetUUIDString(SecretPointer virSecretPtr, byte[] uuidString); - public String virSecretGetUsageID(SecretPointer virSecretPtr); - public Pointer virSecretGetValue(SecretPointer virSecretPtr, LongByReference value_size, int flags); - public String virSecretGetXMLDesc(SecretPointer virSecretPtr, int flags); - public SecretPointer virSecretLookupByUsage(ConnectionPointer virConnectPtr, int usageType, String usageID); - public SecretPointer virSecretLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); - public SecretPointer virSecretLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); - public int virSecretSetValue(SecretPointer virSecretPtr, String value, NativeLong value_size, int flags); - public int virSecretSetValue(SecretPointer virSecretPtr, byte[] value, NativeLong value_size, int flags); - public int virSecretUndefine(SecretPointer virSecretPtr); + ConnectionPointer virSecretGetConnect(SecretPointer virSecretPtr); + int virSecretFree(SecretPointer virSecretPtr); + SecretPointer virSecretDefineXML(ConnectionPointer virConnectPtr, String xml, int flags); + int virSecretGetUUID(SecretPointer virSecretPtr, byte[] uuidString); + int virSecretGetUUIDString(SecretPointer virSecretPtr, byte[] uuidString); + String virSecretGetUsageID(SecretPointer virSecretPtr); + Pointer virSecretGetValue(SecretPointer virSecretPtr, LongByReference value_size, int flags); + String virSecretGetXMLDesc(SecretPointer virSecretPtr, int flags); + SecretPointer virSecretLookupByUsage(ConnectionPointer virConnectPtr, int usageType, String usageID); + SecretPointer virSecretLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); + SecretPointer virSecretLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); + int virSecretSetValue(SecretPointer virSecretPtr, String value, NativeLong value_size, int flags); + int virSecretSetValue(SecretPointer virSecretPtr, byte[] value, NativeLong value_size, int flags); + int virSecretUndefine(SecretPointer virSecretPtr); //Stream Methods - public int virStreamAbort(StreamPointer virStreamPtr) ; - public int virStreamEventAddCallback(StreamPointer virStreamPtr, int events, Libvirt.VirStreamEventCallback cb, + int virStreamAbort(StreamPointer virStreamPtr) ; + int virStreamEventAddCallback(StreamPointer virStreamPtr, int events, Libvirt.VirStreamEventCallback cb, Pointer opaque, Libvirt.VirFreeCallback ff); - public int virStreamEventUpdateCallback(StreamPointer virStreamPtr, int events); - public int virStreamEventRemoveCallback(StreamPointer virStreamPtr); - public int virStreamFinish(StreamPointer virStreamPtr) ; - public int virStreamFree(StreamPointer virStreamPtr) ; - public StreamPointer virStreamNew(ConnectionPointer virConnectPtr, int flags) ; - public int virStreamSend(StreamPointer virStreamPtr, String data, NativeLong size); - public int virStreamSendAll(StreamPointer virStreamPtr, Libvirt.VirStreamSourceFunc handler, Pointer opaque); - public int virStreamRecv(StreamPointer virStreamPtr, byte[] data, NativeLong length); - public int virStreamRecvAll(StreamPointer virStreamPtr, Libvirt.VirStreamSinkFunc handler, Pointer opaque); + int virStreamEventUpdateCallback(StreamPointer virStreamPtr, int events); + int virStreamEventRemoveCallback(StreamPointer virStreamPtr); + int virStreamFinish(StreamPointer virStreamPtr) ; + int virStreamFree(StreamPointer virStreamPtr) ; + StreamPointer virStreamNew(ConnectionPointer virConnectPtr, int flags) ; + int virStreamSend(StreamPointer virStreamPtr, String data, NativeLong size); + int virStreamSendAll(StreamPointer virStreamPtr, Libvirt.VirStreamSourceFunc handler, Pointer opaque); + int virStreamRecv(StreamPointer virStreamPtr, byte[] data, NativeLong length); + int virStreamRecvAll(StreamPointer virStreamPtr, Libvirt.VirStreamSinkFunc handler, Pointer opaque); //DomainSnapshot Methods - public DomainSnapshotPointer virDomainSnapshotCreateXML(DomainPointer virDomainPtr, String xmlDesc, int flags); - public DomainSnapshotPointer virDomainSnapshotCurrent(DomainPointer virDomainPtr, int flags); - public int virDomainSnapshotDelete(DomainSnapshotPointer virDomainSnapshotPtr, int flags); - public String virDomainSnapshotGetXMLDesc(DomainSnapshotPointer virDomainSnapshotPtr, int flags); - public int virDomainSnapshotFree(DomainSnapshotPointer virDomainSnapshotPtr); - public int virDomainSnapshotListNames(DomainPointer virDomainPtr, String[] names, int nameslen, int flags); - public DomainSnapshotPointer virDomainSnapshotLookupByName(DomainPointer virDomainPtr, String name, int flags); - public int virDomainSnapshotNum(DomainPointer virDomainPtr, int flags); + DomainSnapshotPointer virDomainSnapshotCreateXML(DomainPointer virDomainPtr, String xmlDesc, int flags); + DomainSnapshotPointer virDomainSnapshotCurrent(DomainPointer virDomainPtr, int flags); + int virDomainSnapshotDelete(DomainSnapshotPointer virDomainSnapshotPtr, int flags); + String virDomainSnapshotGetXMLDesc(DomainSnapshotPointer virDomainSnapshotPtr, int flags); + int virDomainSnapshotFree(DomainSnapshotPointer virDomainSnapshotPtr); + int virDomainSnapshotListNames(DomainPointer virDomainPtr, String[] names, int nameslen, int flags); + DomainSnapshotPointer virDomainSnapshotLookupByName(DomainPointer virDomainPtr, String name, int flags); + int virDomainSnapshotNum(DomainPointer virDomainPtr, int flags); // Network Filter Methods - public String virNWFilterGetXMLDesc(NetworkFilterPointer virNWFilterPtr, int flags); - public NetworkFilterPointer virNWFilterDefineXML(ConnectionPointer virConnectPtr, String xml); - public int virNWFilterFree(NetworkFilterPointer virNWFilterPtr); - public NetworkFilterPointer virNWFilterLookupByName(ConnectionPointer virConnectPtr, String name); - public NetworkFilterPointer virNWFilterLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); - public NetworkFilterPointer virNWFilterLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); - public String virNWFilterGetName(NetworkFilterPointer virNWFilterPtr); - public int virNWFilterGetUUID(NetworkFilterPointer virNWFilterPtr, byte[] uuidString); - public int virNWFilterGetUUIDString(NetworkFilterPointer virNWFilterPtr, byte[] uuidString); - public int virNWFilterUndefine(NetworkFilterPointer virNWFilterPtr); + String virNWFilterGetXMLDesc(NetworkFilterPointer virNWFilterPtr, int flags); + NetworkFilterPointer virNWFilterDefineXML(ConnectionPointer virConnectPtr, String xml); + int virNWFilterFree(NetworkFilterPointer virNWFilterPtr); + NetworkFilterPointer virNWFilterLookupByName(ConnectionPointer virConnectPtr, String name); + NetworkFilterPointer virNWFilterLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes); + NetworkFilterPointer virNWFilterLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr); + String virNWFilterGetName(NetworkFilterPointer virNWFilterPtr); + int virNWFilterGetUUID(NetworkFilterPointer virNWFilterPtr, byte[] uuidString); + int virNWFilterGetUUIDString(NetworkFilterPointer virNWFilterPtr, byte[] uuidString); + int virNWFilterUndefine(NetworkFilterPointer virNWFilterPtr); } -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

This prevents warnings like this: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds --- build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 0b009aa..158a8a5 100644 --- a/build.xml +++ b/build.xml @@ -42,8 +42,8 @@ </target> <target name="build" depends="init" description="builds the code and jar files"> - <javac srcdir="src/main/java" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" /> - <javac srcdir="src/test/java" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" /> + <javac srcdir="src/main/java" debug="${javac.debug}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" /> + <javac srcdir="src/test/java" debug="${javac.debug}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" /> <jar destfile="${jar.file}" basedir="target/classes" /> </target> -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

This requires a findbugs installation and the findbugs ant library. --- findbugs.xml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/findbugs.xml b/findbugs.xml new file mode 100644 index 0000000..18d51f2 --- /dev/null +++ b/findbugs.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- This runs the findbugs [http://findbugs.sourceforge.net/] ant task for --> +<!-- the libvirt-java jar file. --> + +<!-- You must have findbugs installed and Ant needs to be able to --> +<!-- locate the findbugs-java.jar file. --> + +<!-- Either use the -lib command line option or copy this jar --> +<!-- to ${user.home}/.ant/lib or ${ant.home}/lib. --> + +<!-- E.g. --> + +<!-- "ant -Dfindbugs.home=/path/fb -lib /path/fb/lib/findbugs-ant.jar -f findbugs.xml" --> + +<project name="Libvirt Java Bindings - Findbugs" default="findbugs"> + <!-- findbugs task definition --> + <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask" /> + + <!-- enable debugging to let findbugs report line numbers --> + <property name="javac.debug" value="on" /> + + <import file="build.xml"/> + + <property name="findbugs.output" value="text" /> + + <target name="findbugs" depends="build"> + <findbugs home="${findbugs.home}" + output="${findbugs.output}" > + <auxClasspath refid="compile.classpath" /> + <sourcePath path="${basedir}/src/main/java" /> + <class location="${jar.file}" /> + </findbugs> + </target> + +</project> -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Just use virGetLastError instead of virCopyLastError. Calling virResetLastError is unnecessary because every public libvirt function will first reset the error when being called. --- src/main/java/org/libvirt/ErrorHandler.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/libvirt/ErrorHandler.java b/src/main/java/org/libvirt/ErrorHandler.java index 543829e..4dd7c90 100644 --- a/src/main/java/org/libvirt/ErrorHandler.java +++ b/src/main/java/org/libvirt/ErrorHandler.java @@ -20,14 +20,11 @@ public class ErrorHandler { * @throws LibvirtException */ public static void processError(Libvirt libvirt) throws LibvirtException { - virError vError = new virError(); - int errorCode = libvirt.virCopyLastError(vError); - if (errorCode > 0) { + virError vError = libvirt.virGetLastError(); + if (vError != null) { Error error = new Error(vError); - libvirt.virResetLastError(); /* - * FIXME: Don't throw exceptions for VIR_ERR_WARNING - * level errors + * Don't throw exceptions for VIR_ERR_WARNING level errors */ if (error.getLevel() == Error.ErrorLevel.VIR_ERR_ERROR) { throw new LibvirtException(error); -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Every class contained a member called "libvirt". This member was initialized during construction to refer to the Connect.libvirt member variable, which in turn referred to the static jna.Libvirt.INSTANCE field. Add a Library class which contains a static "libvirt" field and import this field statically for convenient access. --- src/main/java/org/libvirt/Connect.java | 16 +-------------- src/main/java/org/libvirt/Device.java | 7 +------ src/main/java/org/libvirt/Domain.java | 7 +------ src/main/java/org/libvirt/DomainSnapshot.java | 7 +------ src/main/java/org/libvirt/Interface.java | 7 +------ src/main/java/org/libvirt/Library.java | 26 +++++++++++++++++++++++++ src/main/java/org/libvirt/Network.java | 7 +------ src/main/java/org/libvirt/NetworkFilter.java | 7 +------ src/main/java/org/libvirt/Secret.java | 7 +------ src/main/java/org/libvirt/StoragePool.java | 7 +------ src/main/java/org/libvirt/StorageVol.java | 7 +------ src/main/java/org/libvirt/Stream.java | 7 +------ 12 files changed, 37 insertions(+), 75 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index e02c601..ae306d6 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -15,6 +15,7 @@ import org.libvirt.jna.StorageVolPointer; import org.libvirt.jna.StreamPointer; import org.libvirt.jna.virConnectAuth; import org.libvirt.jna.virNodeInfo; +import static org.libvirt.Library.libvirt; import com.sun.jna.Memory; import com.sun.jna.NativeLong; @@ -28,16 +29,6 @@ import com.sun.jna.ptr.LongByReference; */ public class Connect { - // Load the native part - static { - Libvirt.INSTANCE.virInitialize(); - try { - ErrorHandler.processError(Libvirt.INSTANCE); - } catch (Exception e) { - e.printStackTrace(); - } - } - /** * Creates a new connection object from the domain. If all you want is the * existing domain's connection, use the getConnection method directly. Thie @@ -135,11 +126,6 @@ public class Connect { protected ConnectionPointer VCP; /** - * The libvirt library - */ - Libvirt libvirt = Libvirt.INSTANCE; - - /** * Protected constructor to return a Connection with ConnectionPointer */ Connect(ConnectionPointer ptr) { diff --git a/src/main/java/org/libvirt/Device.java b/src/main/java/org/libvirt/Device.java index bc25258..416e06a 100644 --- a/src/main/java/org/libvirt/Device.java +++ b/src/main/java/org/libvirt/Device.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.DevicePointer; import org.libvirt.jna.Libvirt; +import static org.libvirt.Library.libvirt; /** * A device which is attached to a node @@ -19,11 +20,6 @@ public class Device { private Connect virConnect; /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - - /** * Constructs a Device object from a DevicePointer, and a Connect object. * * @param virConnect @@ -34,7 +30,6 @@ public class Device { Device(Connect virConnect, DevicePointer VDP) { this.virConnect = virConnect; this.VDP = VDP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index f4f5225..45fba26 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -11,6 +11,7 @@ import org.libvirt.jna.virDomainJobInfo; import org.libvirt.jna.virDomainMemoryStats; import org.libvirt.jna.virSchedParameter; import org.libvirt.jna.virVcpuInfo; +import static org.libvirt.Library.libvirt; import com.sun.jna.Native; import com.sun.jna.NativeLong; @@ -86,11 +87,6 @@ public class Domain { private Connect virConnect; /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - - /** * Constructs a Domain object from a known native DomainPointer, and a * Connect object. * @@ -102,7 +98,6 @@ public class Domain { Domain(Connect virConnect, DomainPointer VDP) { this.virConnect = virConnect; this.VDP = VDP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/DomainSnapshot.java b/src/main/java/org/libvirt/DomainSnapshot.java index 3083ca0..355d9d0 100644 --- a/src/main/java/org/libvirt/DomainSnapshot.java +++ b/src/main/java/org/libvirt/DomainSnapshot.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.DomainSnapshotPointer; import org.libvirt.jna.Libvirt; +import static org.libvirt.Library.libvirt; public class DomainSnapshot { @@ -15,15 +16,9 @@ public class DomainSnapshot { */ private Connect virConnect; - /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - public DomainSnapshot(Connect virConnect, DomainSnapshotPointer VDSP) { this.VDSP = VDSP; this.virConnect = virConnect; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/Interface.java b/src/main/java/org/libvirt/Interface.java index 17c189d..684adca 100644 --- a/src/main/java/org/libvirt/Interface.java +++ b/src/main/java/org/libvirt/Interface.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.InterfacePointer; import org.libvirt.jna.Libvirt; +import static org.libvirt.Library.libvirt; /** * A device which is attached to a node @@ -24,11 +25,6 @@ public class Interface { private Connect virConnect; /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - - /** * Constructs an Interface object from an InterfacePointer, and a Connect * object. * @@ -40,7 +36,6 @@ public class Interface { Interface(Connect virConnect, InterfacePointer VIP) { this.virConnect = virConnect; this.VIP = VIP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java new file mode 100644 index 0000000..035ed06 --- /dev/null +++ b/src/main/java/org/libvirt/Library.java @@ -0,0 +1,26 @@ +package org.libvirt; + +import org.libvirt.jna.Libvirt; + +/** + * This class represents an instance of the JNA mapped libvirt + * library. + * + * The library will get loaded when first accessing this class. + */ +final class Library { + final static Libvirt libvirt; + + // Load the native part + static { + Libvirt.INSTANCE.virInitialize(); + libvirt = Libvirt.INSTANCE; + try { + ErrorHandler.processError(Libvirt.INSTANCE); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Library() {} +} diff --git a/src/main/java/org/libvirt/Network.java b/src/main/java/org/libvirt/Network.java index acaef0e..bdb0d78 100644 --- a/src/main/java/org/libvirt/Network.java +++ b/src/main/java/org/libvirt/Network.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.Libvirt; import org.libvirt.jna.NetworkPointer; +import static org.libvirt.Library.libvirt; import com.sun.jna.Native; import com.sun.jna.ptr.IntByReference; @@ -22,11 +23,6 @@ public class Network { protected Connect virConnect; /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - - /** * Constructs a Network object from a known native virNetworkPtr, and a * Connect object. For use when native libvirt returns a virConnectPtr, i.e. * error handling. @@ -37,7 +33,6 @@ public class Network { Network(Connect virConnect, NetworkPointer VNP) { this.virConnect = virConnect; this.VNP = VNP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/NetworkFilter.java b/src/main/java/org/libvirt/NetworkFilter.java index 7bc07a5..ba4d2ea 100644 --- a/src/main/java/org/libvirt/NetworkFilter.java +++ b/src/main/java/org/libvirt/NetworkFilter.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.Libvirt; import org.libvirt.jna.NetworkFilterPointer; +import static org.libvirt.Library.libvirt; import com.sun.jna.Native; @@ -16,15 +17,9 @@ public class NetworkFilter { */ private Connect virConnect; - /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - public NetworkFilter(Connect virConnect, NetworkFilterPointer NFP) { this.NFP = NFP; this.virConnect = virConnect; - libvirt = virConnect.libvirt; } @Override diff --git a/src/main/java/org/libvirt/Secret.java b/src/main/java/org/libvirt/Secret.java index 888cdf3..5332e02 100644 --- a/src/main/java/org/libvirt/Secret.java +++ b/src/main/java/org/libvirt/Secret.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.Libvirt; import org.libvirt.jna.SecretPointer; +import static org.libvirt.Library.libvirt; import com.sun.jna.Native; import com.sun.jna.NativeLong; @@ -24,15 +25,9 @@ public class Secret { */ private Connect virConnect; - /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - Secret(Connect virConnect, SecretPointer VSP) { this.virConnect = virConnect; this.VSP = VSP; - libvirt = virConnect.libvirt; } @Override diff --git a/src/main/java/org/libvirt/StoragePool.java b/src/main/java/org/libvirt/StoragePool.java index 29a18ed..2d59f68 100644 --- a/src/main/java/org/libvirt/StoragePool.java +++ b/src/main/java/org/libvirt/StoragePool.java @@ -4,6 +4,7 @@ import org.libvirt.jna.Libvirt; import org.libvirt.jna.StoragePoolPointer; import org.libvirt.jna.StorageVolPointer; import org.libvirt.jna.virStoragePoolInfo; +import static org.libvirt.Library.libvirt; import com.sun.jna.Native; import com.sun.jna.ptr.IntByReference; @@ -50,11 +51,6 @@ public class StoragePool { protected Connect virConnect; /** - * the libvirt instance - */ - protected Libvirt libvirt; - - /** * Constructs a VirStoragePool object from a known native virStoragePoolPtr, * and a VirConnect object. For use when native libvirt returns a * virStoragePoolPtr, i.e. error handling. @@ -67,7 +63,6 @@ public class StoragePool { StoragePool(Connect virConnect, StoragePoolPointer VSPP) { this.virConnect = virConnect; this.VSPP = VSPP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/StorageVol.java b/src/main/java/org/libvirt/StorageVol.java index e2bc717..4b9db80 100644 --- a/src/main/java/org/libvirt/StorageVol.java +++ b/src/main/java/org/libvirt/StorageVol.java @@ -4,6 +4,7 @@ import org.libvirt.jna.Libvirt; import org.libvirt.jna.StoragePoolPointer; import org.libvirt.jna.StorageVolPointer; import org.libvirt.jna.virStorageVolInfo; +import static org.libvirt.Library.libvirt; /** * An acutal storage bucket. @@ -43,11 +44,6 @@ public class StorageVol { protected Connect virConnect; /** - * the libvirt instance - */ - protected Libvirt libvirt; - - /** * Constructs a VirStorageVol object from a known native virStoragePoolPtr, * and a VirConnect object. For use when native libvirt returns a * virStorageVolPtr, i.e. error handling. @@ -60,7 +56,6 @@ public class StorageVol { StorageVol(Connect virConnect, StorageVolPointer VSVP) { this.virConnect = virConnect; this.VSVP = VSVP; - libvirt = virConnect.libvirt; } /** diff --git a/src/main/java/org/libvirt/Stream.java b/src/main/java/org/libvirt/Stream.java index 06b67cf..84e300c 100644 --- a/src/main/java/org/libvirt/Stream.java +++ b/src/main/java/org/libvirt/Stream.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.Libvirt; import org.libvirt.jna.StreamPointer; +import static org.libvirt.Library.libvirt; import com.sun.jna.NativeLong; @@ -19,15 +20,9 @@ public class Stream { */ private Connect virConnect; - /** - * The libvirt connection from the hypervisor - */ - protected Libvirt libvirt; - Stream(Connect virConnect, StreamPointer VSP) { this.virConnect = virConnect; this.VSP = VSP; - libvirt = virConnect.libvirt; } /** -- 1.7.9.5 -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

ping? Anyone care to review these patches, before someone redoes this work again...? At Fri, 12 Oct 2012 12:33:01 +0200, Claudio Bley wrote:
Hi.
/ something went not quite right the last time, I'm resending this / / series. Please ignore my previous mails. /
Just sending off a few patches that have piled up during the last few months.
Patch #1 to #7 and #9 to #10 and #12 contain mostly cosmetic changes resp. changes to the build system.
Patch #8 changes the handling of errors. It is unnecessary trying to retrieve an error when the libvirt function called did not signal any. Also, some functions never fail (return void).
Patch #11 changes how errors are checked. This avoids copying and freeing an error object and hence a few JVM to native calls.
Patch #13 fixes all the memory leaks I encountered by using my GDB memcheck.py script. Running the junit tests under GDB's supervision yielded 750 places of (potential) memory leaks, pointing to calls of these libvirt functions:
virDomainDefineXML, virInterfaceGetXMLDesc, virConnectListDefinedDomains, virStoragePoolLookupByName, virDomainLookupByName, virNetworkGetBridgeName, virNetworkLookupByUUIDString, virDomainLookupByUUID, virDomainLookupByUUIDString, virConnectListInterfaces, virDomainGetOSType, virConnectListDefinedNetworks, virNetworkCreateXML, virStoragePoolDefineXML, virConnectOpen, virDomainCreateXML, virNetworkDefineXML, virNetworkLookupByName, virCopyLastError, virNetworkCreate, virNetworkLookupByUUID, virInterfaceLookupByName, virConnectGetHostname, virDomainGetXMLDesc, virConnectListNetworks, virNetworkGetXMLDesc
After applying patch #13, the script reports this:
1. @140737220948192 #1 __GI___strdup __GI___strdup strdup.c:45 #2 ... [1] #3 Java_java_util_zip_ZipFile_open ? ?:0 #4 ... [5] 2. @140737221175744 #1 virAlloc virAlloc /build/buildd/libvirt-0.9.12/./src/util/memory.c:103 #2 virLastErrorObject virLastErrorObject /build/buildd/libvirt-0.9.12/./src/util/virterror.c:277 #3 virGetLastError virGetLastError /build/buildd/libvirt-0.9.12/./src/util/virterror.c:299 #4 ffi_call_unix64 ? ?:0 #5 ffi_call ? ?:0 #6 ... [1] #7 Java_com_sun_jna_Native_invokePointer ? ?:0 #8 ... [5] 3. @140737220736736 #1 __libc_res_nsend __libc_res_nsend res_send.c:442 #2 __libc_res_nquery __libc_res_nquery res_query.c:226 #3 __libc_res_nquerydomain __libc_res_nquerydomain res_query.c:578 #4 __libc_res_nsearch __libc_res_nsearch res_query.c:416 #5 _nss_dns_gethostbyname3_r _nss_dns_gethostbyname3_r nss_dns/dns-host.c:197 #6 gaih_inet gaih_inet ../sysdeps/posix/getaddrinfo.c:940 #7 __GI_getaddrinfo __GI_getaddrinfo ../sysdeps/posix/getaddrinfo.c:2423 #8 virGetHostname virGetHostname /build/buildd/libvirt-0.9.12/./src/util/util.c:2105 #9 virConnectGetHostname virConnectGetHostname /build/buildd/libvirt-0.9.12/./src/libvirt.c:1724 #10 ffi_call_unix64 ? ?:0 #11 ffi_call ? ?:0 #12 ... [1] #13 Java_com_sun_jna_Native_invokePointer ? ?:0 #14 ... [4] 4. @140737018598944 #1 virAlloc virAlloc /build/buildd/libvirt-0.9.12/./src/util/memory.c:103 #2 virLastErrorObject virLastErrorObject /build/buildd/libvirt-0.9.12/./src/util/virterror.c:277 #3 virResetLastError virResetLastError /build/buildd/libvirt-0.9.12/./src/util/virterror.c:428 #4 virNetworkFree virNetworkFree /build/buildd/libvirt-0.9.12/./src/libvirt.c:10151 #5 ffi_call_unix64 ? ?:0 #6 ffi_call ? ?:0 #7 ... [1] #8 Java_com_sun_jna_Native_invokeInt ? ?:0 #9 ... [2] 5. @140737221440624 #1 __libc_res_nsend __libc_res_nsend res_send.c:442 #2 __libc_res_nquery __libc_res_nquery res_query.c:226 #3 __libc_res_nquerydomain __libc_res_nquerydomain res_query.c:578 #4 __libc_res_nsearch __libc_res_nsearch res_query.c:416 #5 _nss_dns_gethostbyname3_r _nss_dns_gethostbyname3_r nss_dns/dns-host.c:197 #6 gaih_inet gaih_inet ../sysdeps/posix/getaddrinfo.c:940 #7 __GI_getaddrinfo __GI_getaddrinfo ../sysdeps/posix/getaddrinfo.c:2423 #8 virGetHostname virGetHostname /build/buildd/libvirt-0.9.12/./src/util/util.c:2105 #9 virConnectGetHostname virConnectGetHostname /build/buildd/libvirt-0.9.12/./src/libvirt.c:1724 #10 ffi_call_unix64 ? ?:0 #11 ffi_call ? ?:0 #12 ... [1] #13 Java_com_sun_jna_Native_invokePointer ? ?:0 #14 ... [4]
only pointing to the following function calls:
virConnectGetHostname, virNetworkFree, virGetLastError
AFAICS, these are neglectable. Probably just some global memory which is not freed on exit.
(for the record: I'm on Ubuntu Precise, using libvirt 0.9.12. And yes, I did call __libc_freeres on exit.)
Patch #14 removes functions that should have never been wrapped. These functions do not increase the ref count and hence create Java objects that actually do not represent "real" instances on the libvirt side.
I have tested with JNA 3.3.0, 3.4.{0, 1, 2}. I had JVM crashes repeatedly with all JNA versions before 3.4.2. So, I strongly recommend to use JNA 3.4.2.
Claudio Bley (15): Explicitly set includeAntRuntime to false for javac tasks. Introduce a javac.debug property. Add findbugs build file for ant. Make finalize() methods protected. Remove redundant public modifier from Libvirt interface methods. Change visibility of class members to private to enforce encapsulation. Mark virConnCopyLastError and virConnGetLastError as deprecated. Call processError only if a libvirt function indicates an error. Split JUnit tests and use a fixture for Connect. Split "build" target and automatically rebuild out of date files. Avoid unnecessary copying and calling virResetLastError. Remove the libvirt instance attribute from all classes. Fix memory leaks for libvirt functions returning newly allocated memory. Remove functions not intended to be used by libvirt bindings. Explicitely define the order of a struct's fields.
build.xml | 37 +- findbugs.xml | 36 ++ src/main/java/org/libvirt/Connect.java | 572 +++++++------------- src/main/java/org/libvirt/Device.java | 9 +- src/main/java/org/libvirt/Domain.java | 33 +- src/main/java/org/libvirt/DomainSnapshot.java | 9 +- src/main/java/org/libvirt/Error.java | 24 +- src/main/java/org/libvirt/ErrorHandler.java | 9 +- src/main/java/org/libvirt/Interface.java | 19 +- src/main/java/org/libvirt/Library.java | 88 +++ src/main/java/org/libvirt/LibvirtException.java | 2 +- src/main/java/org/libvirt/Network.java | 26 +- src/main/java/org/libvirt/NetworkFilter.java | 9 +- src/main/java/org/libvirt/Secret.java | 9 +- src/main/java/org/libvirt/StoragePool.java | 9 +- src/main/java/org/libvirt/StorageVol.java | 9 +- src/main/java/org/libvirt/Stream.java | 11 +- src/main/java/org/libvirt/jna/Libvirt.java | 502 ++++++++--------- src/main/java/org/libvirt/jna/virConnectAuth.java | 10 + .../java/org/libvirt/jna/virConnectCredential.java | 12 + .../java/org/libvirt/jna/virDomainBlockInfo.java | 8 + .../java/org/libvirt/jna/virDomainBlockStats.java | 11 + src/main/java/org/libvirt/jna/virDomainInfo.java | 11 + .../org/libvirt/jna/virDomainInterfaceStats.java | 13 + .../java/org/libvirt/jna/virDomainJobInfo.java | 18 + .../java/org/libvirt/jna/virDomainMemoryStats.java | 7 + src/main/java/org/libvirt/jna/virError.java | 19 + src/main/java/org/libvirt/jna/virNodeInfo.java | 15 + .../java/org/libvirt/jna/virSchedParameter.java | 9 + .../java/org/libvirt/jna/virStoragePoolInfo.java | 10 + .../java/org/libvirt/jna/virStorageVolInfo.java | 8 + src/main/java/org/libvirt/jna/virVcpuInfo.java | 9 + src/test/java/org/libvirt/TestJavaBindings.java | 50 +- src/test/java/org/libvirt/TestLibvirtGlobals.java | 21 + 34 files changed, 883 insertions(+), 761 deletions(-) create mode 100644 findbugs.xml create mode 100644 src/main/java/org/libvirt/Library.java create mode 100644 src/test/java/org/libvirt/TestLibvirtGlobals.java
-- 1.7.9.5
-- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org>
Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern
-- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

On Wed, Nov 28, 2012 at 10:51:56 +0100, Claudio Bley wrote:
ping?
Anyone care to review these patches, before someone redoes this work again...?
ACK to the whole series. I looked at the individual patches and while I'm not a java nor jna expert, the patches look like they're doing the right thing :-) Jirka

At Mon, 7 Jan 2013 15:31:30 +0100, Jiri Denemark wrote:
On Wed, Nov 28, 2012 at 10:51:56 +0100, Claudio Bley wrote:
ping?
Anyone care to review these patches, before someone redoes this work again...?
ACK to the whole series. I looked at the individual patches and while I'm not a java nor jna expert, the patches look like they're doing the right thing :-)
Thanks, pushed. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern
participants (4)
-
Benjamin Wang (gendwang)
-
Claudio Bley
-
Daniel Veillard
-
Jiri Denemark