I'm using the VirtualBox Java API (Version VirtualBoxSDK-5.1.22-115126) on a Windows Host with the VirtualBox Web Service (VBoxWebSrv.exe).
I wrote a method to restore a certain snapshot for a given machine.
Most times it works, but sometimes I get the exception with the error code 0x800706be when I call IProgress.waitForCompletion() after I called IMachine.restoreSnapshot().
The affected lines:
Code: Select all
[...]
progress = session.getMachine().restoreSnapshot(snapshot);
progress.waitForCompletion(20000); // <- Here the exception occurs
[...]
Code: Select all
org.virtualbox_5_1.VBoxException: VirtualBox error: rc=0x800706be
at org.virtualbox_5_1.IProgress.waitForCompletion(IProgress.java:531)
at VboxApiVmCtrl.restoreSnap(VboxApiVmCtrl.java:654)
at Main.main(Main.java:79)
Caused by: org.virtualbox_5_1.jaxws.RuntimeFaultMsg: VirtualBox error: rc=0x800706be
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:135)
at com.sun.xml.internal.ws.client.sei.StubHandler.readResponse(StubHandler.java:238)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:189)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:276)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:104)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
at com.sun.proxy.$Proxy35.iProgressWaitForCompletion(Unknown Source)
at org.virtualbox_5_1.IProgress.waitForCompletion(IProgress.java:523)
... 2 more
(The method first stops the machine, then restores the snapshot and then starts the machine again.)
Code: Select all
public boolean restoreSnap(String vmUid, String snapUid) {
// get Session
ISession session = mgr.getSessionObject();
try {
// get VM
IMachine vm = mgr.getVBox().findMachine(vmUid);
// Lock VM to Session
vm.lockMachine(session, LockType.Shared); // >>> LOCKED!
// get Console to manage the VM
IConsole console = session.getConsole();
IProgress progress = null;
// -------------- STOP MACHINE (IF RUNNING) --------------
System.out.println("TRY TO STOP THE MACHINE...");
// Console is NULL, if Machine is not running
if (console != null) {
// Stop machine
progress = console.powerDown();
progress.waitForCompletion(20000);
} else {
System.out.println("MACHINE NOT RUNNING.");
}
// -------------- RESTORE SNAPSHOT --------------
// get Snapshot by UUID
ISnapshot snapshot = vm.findSnapshot(snapUid);
System.out.println("TRY TO RESTORE SNAPSHOT: " + snapshot.getName());
progress = session.getMachine().restoreSnapshot(snapshot);
progress.waitForCompletion(20000); // <- Here: ERROR 0x800706be
// Wait until session isn't locked else -> else BUSY excpetion when try to start.
int waitCount = 0;
while (session.getState() == SessionState.Locked && (waitCount < 10)) {
waitMs(150); // wait 150 ms
waitCount++;
}
// -------------- START VM --------------
// start machine if it is not running
if (vm.getState() != MachineState.Running) {
// UNLOCK IF SESSION IS LOCKED
if (session.getState() == SessionState.Locked) {
System.out.println("SESSION LOCKED -> UNLOCK...");
session.unlockMachine();
}
// WAIT...
waitCount = 0;
while (vm.getSessionState() == SessionState.Locked && (waitCount < 10)) {
waitMs(150); // wait 150 ms
waitCount++;
}
System.out.println("STARTING MACHINE...");
// Without waiting, here occurs :
// org.virtualbox_5_1.VBoxException: VirtualBox error: rc=0x80bb0007 The given session is busy
progress = vm.launchVMProcess(session, "gui", "");
progress.waitForCompletion(20000);
return true;
} else {
System.out.println("MACHINE IS ALREADY RUNNING. DON'T START...");
}
} catch (VBoxException e) {
printErrorInfo(e); // Method that prints some error infos
e.printStackTrace();
} finally {
// After everything is done, unlock session.
System.out.println("TRY TO UNLOCK SESSION...");
if (session.getState() == SessionState.Locked) {
// Unlock
System.out.println("Unlock Machine from Session.");
session.unlockMachine(); // UNLOCK!!!! <<<<<<<<<<<<
System.out.println("Session State: " + session.getState());
} else {
System.out.println("DON'T UNLOCK, BECAUSE SESSION IS NOT LOCKED.");
}
}
return false;
}
The guest machine with which I'm testing the method is a Windows 7 machine.
I would be really happy, if someone could help me!