noteirak wrote:Can you produce a standalone piece of code that reproduces the issue? Right now, only part of your code is visible which doesn't allow to really see where a possible mistake is.
Sure. Following is a complete test code.
Note that the machine expected to be cloned has snapshots and is powered off.
Run with following arguments: "-w -server h t t p : / /<ip>:<port>"
Code: Select all
import java.util.ArrayList;
import java.util.List;
import org.virtualbox_5_1.CloneMode;
import org.virtualbox_5_1.CloneOptions;
import org.virtualbox_5_1.IMachine;
import org.virtualbox_5_1.IProgress;
import org.virtualbox_5_1.IVirtualBox;
import org.virtualbox_5_1.IVirtualBoxErrorInfo;
import org.virtualbox_5_1.VBoxException;
import org.virtualbox_5_1.VirtualBoxManager;
public class TestLinkedClone
{
static void testLinkedClone(VirtualBoxManager mgr, IVirtualBox vbox)
{
IMachine m = vbox.getMachines().get(0);
String name = m.getName();
System.out.println("\nAttempting to clone VM '" + name + "'");
IMachine createdMachine = vbox.createMachine(
null,
"Cloned_machine",
null,
m.getOSTypeId(),
null);
List<CloneOptions> options = new ArrayList<>();
options.add(CloneOptions.Link);
IProgress cloneProgress = m.cloneTo(createdMachine, CloneMode.MachineState, options);
boolean success = progressBar(mgr, cloneProgress, 10000);
if (success) {
vbox.registerMachine(createdMachine);
}
// process system event queue
mgr.waitForEvents(0);
}
static boolean progressBar(VirtualBoxManager mgr, IProgress p, long waitMillis)
{
long end = System.currentTimeMillis() + waitMillis;
while (!p.getCompleted())
{
// process system event queue
mgr.waitForEvents(0);
// wait for completion of the task, but at most 200 msecs
p.waitForCompletion(200);
if (System.currentTimeMillis() >= end)
return false;
}
return true;
}
static void printErrorInfo(VBoxException e)
{
System.out.println("VBox error: " + e.getMessage());
System.out.println("Error cause message: " + e.getCause());
System.out.println("Overall result code: " + Integer.toHexString(e.getResultCode()));
int i = 1;
for (IVirtualBoxErrorInfo ei = e.getVirtualBoxErrorInfo(); ei != null; ei = ei.getNext(), i++)
{
System.out.println("Detail information #" + i);
System.out.println("Error mesage: " + ei.getText());
System.out.println("Result code: " + Integer.toHexString(ei.getResultCode()));
// optional, usually provides little additional information:
System.out.println("Component: " + ei.getComponent());
System.out.println("Interface ID: " + ei.getInterfaceID());
}
}
public static void main(String[] args)
{
VirtualBoxManager mgr = VirtualBoxManager.createInstance(null);
boolean ws = false;
String server = null;
String user = null;
String passwd = null;
for (int i = 0; i < args.length; i++)
{
if (args[i].equals("-w"))
ws = true;
else if (args[i].equals("-server"))
server = args[++i];
else if (args[i].equals("-user"))
user = args[++i];
else if (args[i].equals("-passwd"))
passwd = args[++i];
}
if (ws)
{
try {
mgr.connect(server, user, passwd);
} catch (VBoxException e) {
e.printStackTrace();
System.out.println("Cannot connect, start webserver first!");
}
}
try
{
IVirtualBox vbox = mgr.getVBox();
if (vbox != null)
{
System.out.println("VirtualBox version: " + vbox.getVersion() + "\n");
testLinkedClone(mgr, vbox);
System.out.println("done, press Enter...");
int ch = System.in.read();
}
}
catch (VBoxException e)
{
printErrorInfo(e);
System.out.println("Java stack trace:");
e.printStackTrace();
}
catch (RuntimeException e)
{
System.out.println("Runtime error: " + e.getMessage());
e.printStackTrace();
}
catch (java.io.IOException e)
{
e.printStackTrace();
}
// process system event queue
mgr.waitForEvents(0);
if (ws)
{
try {
mgr.disconnect();
} catch (VBoxException e) {
e.printStackTrace();
}
}
mgr.cleanup();
}
}